路飞学城Python-Day8
【11.函数-基本介绍】
函数引出问题:如果出现这个需求,需要监控单位的服务器状况,当CPU/MEMORY/DISK等指标使用量超过阀值时,就发邮件报警
while True: if CPU利用率>90%: #发送邮件提醒 连接服务器 发送邮件 关闭连接 pass if MEMORY利用率>90%: #发送邮件提醒 连接服务器 发送邮件 关闭连接 pass if DISK利用率>90%: #发送邮件提醒 连接服务器 发送邮件 关闭连接 pass
这样的代码虽然实现了功能,但是有很多重复的呢?而且每次报警的其他情况都要重写一次报警的代码,这样太low了
而且存在两个问题:
1.代码重复过多,都是copy and paste 不符合程序员的作业标准
2.如果需要修改发邮件的这段代码,比如发微信功能,那就需要全部都再重复的去修改,这样的问题会非常致命
目前只能这么去做的是需要再学习的,这样就能用到函数了
主要利用函数的特性,把重复的代码提取出来,放在一个公共的地方,起个名字,以后谁需要这段功能,直接调用就可以了
def 发送邮件(内容): #发送邮件提醒 连接服务器 发送邮件 关闭连接 while True: if CPU利用率>90%: 发送邮件("CPU") pass if MEMORY利用率>90%: 发送邮件("MEMORY") pass if DISK利用率>90%: 发送邮件("DISK") pass
def 其实就是define的缩写,解决了致命的问题,以后的代码拓展性很高
好的,我们再看看函数
函数是什么?
函数一词来源于数学,但是编程中的[函数]概念,与数学中的函数是有很大的区别的,具体区别后面会介绍
编程中的函数在英文中也有很多不同的叫法,在BASIC中叫做subroutine(子过程或子程序),在Pascal中叫做producer(过程)和function,在C中只有function,在Java中叫做method
函数的定义
函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需要调用函数名就可以了
def sayhi():#函数名 print("Hello!!!") sayhi()#调用函数
如果直接写sayhi,不写括号,打印的就是这个函数占用的内存地址,只有加上括号才是调用了这个函数的方法
还有一种版本是可以加上参数的
a, b = 5, 8 c = a**b print(c) #改成函数的方式 def calc(x,y): res = x**y return res #返回函数执行后的结果 c = calc(a,b) print(c)
特性:
1.减少重复代码
2.使程序变的可拓展
3.使程序变的易于维护
注意:函数名不要大写,函数名小写就可以
【12.函数-默认参数】
参数可以让你的函数更加灵活,不只是做简单的动作,还可以根据调用时传参的不同来决定函数内部的执行流程
形参变量
只有在被调用的时候才分配内存单元,在调用结束后,就即刻释放所分配的内存单元,因此,形参只在函数内部有效,函数调用结束返回的主调用函数后则不能再使用形参变量
实参
可以是常量,变量,表达式,函数等,无论是何种类型的量,在进行函数的调用时,它们都必须要有确定的值,以便于把这些值传送给形参,因此应预先用赋值,输入等办法使参数获得确定值
def calc(x,y):#这里的x,y就是形参 res = x**y return res c = calc(a,b)#这里的a,b就是实参 print(c)
默认参数:
默认参数可以为了程序在编写的时候少写些代码
def stu_register(name, age, country, course): print("-----注册学生信息--------") print("姓名", name) print("年龄", age) print("国籍", country) print("课程", course) stu_register("XXX", 11, "CN", "python") stu_register("YYY", 21, "CN", "Linux") stu_register("KKK", 17, "CN", "python")
发现country这个参数基本都是"CN"
就像我们在网站上注册用户,像国籍这种信息,不填写都会默认是中国的,这就是通过默认参数实现的,把country变成默认参数非常简单
def stu_register(name, age, course, country = "CN")
这里调整了函数的默认值,就需要把默认参数放在函数的最后的位置
【13.函数-关键参数】
位置参数:按位置顺序传参数的就是位置参数
默认参数:放在函数最后给函数赋默认值
关键参数:正常情况下,给函数传参数要按顺序,不想按顺序就可以用关键参数,只需要指定参数名即可(指定了参数名的参数就是关键参数)
但是记住一个要求就是,关键参数必须放在位置参数(以位置顺序确定对应关系的参数)之后
def stu_register(name, age, country = "CN", course = "Py"): print("-----注册学生信息--------") print("姓名", name) print("年龄", age) print("国籍", country) print("课程", course) stu_register("XXX", course = 'Py',age = 22, country = 'JP')
【14.函数-非固定参数】
报警的机制,发给1个运维人员,信息是一样的信息
def send_alert(msg, user):
pass
随着部门发展,运维人员发展成了10个
send_alert("XXX", "panda")
可以在user上加*user,这样就允许传多个参数,多个参数就会全部打包成元祖
def send_alert(msg, *users):
for u in users:
print("报警发送", u)
方式一:
如果参数中出现了形参中的有的*,那么传参数的时候就会把所有的参数以元祖的形式打包传入,传递的参数就不再是固定的参数了
方式二:
不止有元祖形式的非固定参数,也可以直接打包成一个列表的形式
send_alert("XXX", *["panda","pandaboy"])#在列表前加上*就会自动的把整个列表封装成元祖的形式打包发给函数
带*的参数后面就不能带其他的参数了,会报错的,因为*的参数会截断
【15.函数-非固定参数2】
非固定参数之字典形式
def func(name, *args, **kwargs):
print(name, args, kwargs)
func('Alex', 22, 'XXX')
**kwargs允许传入字典的形式,方式更为灵活,但是占用的空间也更大
【16.函数-返回值】
返回值:根据整改函数的运行结果产生一个结果,然后返回给函数
函数外部的代码要想获取函数的执行结果,就可以在函数里用return语句把结果返回
def stu_register(name, age, course = 'Py', country = 'CN'): print('----注册学生信息-----') print('姓名:', name) print("年龄", age) print('国籍', country) print('课程', course) if age>22: return False else: return True registration_status = stu_register('xxx', 22, course = 'Py', country = 'JP') if registration_status: print('连接成功') else: print('那就不成功')
注意:
1.函数在执行的过程中只要遇到return语句,就会停止执行并返回结果,so也可以理解为return语句代表着函数的结果
2.如果未在函数中指定return,那这个函数的返回值为None
3.return是指一个函数的终止,无论这个函数内部还有多少代码,都不会再去执行了
4.如果有两个return的话,就会执行第一个return,因为第一个return就是函数的结束了,返回多个值就在值后面加上,(逗号),也可以直接返回元祖、列表等
【17.函数-局部变量】
name = "Pandaboy" def change_name(): name = "熊猫大哥哥" print(name) change_name() print(name)
输出的结果
全局变量:定义在函数外部的一级代码,全局都能调用
局部变量的定义:在函数内部定义的变量就是局部变量
局部变量会在函数自己执行完以后就消失
在函数内部可以引用全局变量,如果函数内部和外部都是有相同的变量名时,先调用自己函数内部的变量,由内而外去找,局部只能引用全局变量,不可修改
两个变量的内存地址都不同,函数会先去找自己的变量
能不能直接在函数的内部调用全局变量呢
可以的,函数找变量是有顺序的,会先去找自己内部的,找不到就会去找外部的变量,外部的变量是没办法调用函数内部的变量的
【18.函数-在函数里修改全局变量】
在函数内部写上 global 就可以修改了
不能先在函数的内部定义上变量以后再global,会报错,要想修改全局变量,必须在函数内部先声明
实际开发过程中,不建议在函数的内部去修改全局的变量,不便于以后拓展或者调试
【19.函数-在函数里修改列表数据】
names = ['Alex', 'Panda', 'Boy'] def change_name(): names = ['P','K'] print(names) change_name() print(names)
什么类型的全局变量是可以被函数内部直接就修改?
字典、列表、集合、对象、类都是可以被修改的
字符串、数字等都是不可修改的
【20.函数-嵌套函数】
def func1(): print('alex') def func2(): print('eric') func2() func1()
函数内部套函数
1.函数内部可以再次定义函数,
2.对于函数来说,只要是定义的,不管在内部外部,想要执行函数,都必须要调用函数
age = 19 def func1(): age = 22 print(age) def func2(): age = 80 print(age) func2() func1()
函数的拓展知识:函数会去一层一层的找自己需要的变量,局部变量之间是有等级关系的
【21.函数-作用域】
什么是作用域?
在python中,一个函数就是一个作用域,和(JavaScript)类似
age = 18
def fun1():
age = 90
print('panda')#这些函数内部的代码就被放在了函数的作用域里
def fun2():
age = 99
print('boy')
总结:所有的局部变量其实是放置在其中的作用域里的
对于作用域,定义完成后已经生成,以后再调用的时候就会根据函数的作用关系一层一层的层级关系查找(作用域链向上查找)
age = 18 def func1(): age = 73 def func2(): print(age) return func2 val = func1() val()
输出结果
【22-函数-匿名函数】
匿名函数的引出
def calc(x,y):
return x**y
lambda x, y:x**y 声明一个匿名函数
func = lambda x, y:x**y print(func(2, 6))
输出结果
匿名函数还可以用来判断,最多只能支持三元运算,lambda函数是不支持复杂的逻辑判断的
func = lambda x, y:x*y if x<y else x/y
匿名函数就是把多行的语句调用为一行,匿名函数其实不易读,一般场景下不使用,最多的使用场景就是搭配其他函数使用
搭配方法(列表自乘)
data = list(range(10))
print(data)
for index, i in enumerate(data):
data[index] = i*i
print(data)
lambda搭配map实现列表元素自乘
data = list(range)
print(list(map(lambda x:x*x, data)))
总结:匿名函数的作用:1.节省代码量;2.看着高级
posted on 2018-07-06 09:59 pandaboy1123 阅读(175) 评论(0) 编辑 收藏 举报