1.python中函数定义:函数是逻辑结构化和过程结构化的一种变成方法。
python中函数定义方法:
def test(x):
''The function definitions''
x+=1
return x
def :定义函数的关键字
test :函数名
():可定义形参
‘’‘’:文档描述,非必要
x+=1: 泛指代码块或程序处理逻辑
return: 定义返回值
2.为什么要使用函数
背景摘要:现在需要写一个监控程序,当CPU,MEMORY,DISK等指标的使用量超过阈值时发送报警邮件
while1: if cpu>90%: #发送邮件提醒 连接邮箱服务器 发送邮件 关闭链接 if memory >90%: #发送邮件提醒 连接邮箱服务器 发送邮件 关闭链接 if disk >90% #发送邮件提醒 连接邮箱服务器 发送邮件 关闭链接
def 发送邮件(内容):
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭链接
while 1:
if cpu>90%:
发送邮件('cpu报警')
if memory>90%:
发送邮件('memory报警')
if disk>90%:
发送邮件('disk报警')
总结使用函数的好处:
1.代码重用
2.保持一致性,容易维护
3.可扩展性
3.函数参数
1.形参变量只有在调用时候才分配内存单元,在调用结束时,即刻释放所调用的内存单元。因此,形参只在函数内部有效
函数调用结束返回主调用函数后则不能在使用该形参变量。
2.实参可以使常量,变量,表达式,函数等,无论实参是何种类型的量,在进行函数调用时,它们必须有确定的值,以便把
这些值传给形参。因此应预先用赋值,输入等办法使参数获得确定值。
def calc(x,y): #x,y为形参 res=x**y return res calc(a,b) #a,b为实参 print(calc(a,b))
3.位置参数和关键字
标准调用:实参和形参一一对应;
关键字调用:位置无需固定
def test(x,y,z): print(x) print(y) print(z) test(1,2,3) #位置标准调用 test(x=1,y=3,z=2)#关键字调用
如果混合使用,位置参数一定要在关键字参数的左边
4.默认参数
def handle(x,type='mysql'): print(x,type) handle('hello')#type默认值为'mysql'
handle('hello',1) #重新赋值,覆盖原本默认参数
hello mysql
hello 1
5.参数组
*列表
def test(x,*args): print(x) print(args) test(1,2,3,4,5) test(1,[2,3,4,5]) test(1,*[2,3,4,5])
1 (2, 3, 4, 5) 1 ([2, 3, 4, 5],) 1 (2, 3, 4, 5)
**字典
def test(x,**kwargs): print(x) print(kwargs) test(1,y=2,z=3)
1 {'y': 2, 'z': 3}
def test(x,*args,**kwargs): print(x) print(args) print(kwargs) test(1,2,3,4,5,y=2,z=3)
1 (2, 3, 4, 5) {'y': 2, 'z': 3}
def test(x,*args,**kwargs): print(x) print(args,args[0]) print(kwargs,kwargs.get('z')) test(1,*[2,3,4],**{'y':2,'z':3})
1 (2, 3, 4) 2 {'y': 2, 'z': 3} 3
6.局部变量和全局变量
规则:全局变量名大写,局部变量名小写
在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
#有声明局部变量
NAME = ['上网', '打游戏'] def test(): NAME = '泡妞' print('我的爱好',NAME) test()
我的爱好 泡妞
#无声明局部变量 NAME = ['上网', '打游戏'] def test(): print('我的爱好',NAME) test()
我的爱好 ['上网', '打游戏']
7.返回值
要想获取函数的执行结果,就可以用return语句把结果返回
注意:
- 函数在执行过程中只要遇到return语句,就会停止执行并返回结果,so 也可以理解为 return 语句代表着函数的结束
- 如果未在函数中指定return,那这个函数的返回值为None
8.嵌套函数
def huangwei(): name = '黄伟' print(name) def liuyang(): name = '刘洋' print(name) def nulige(): name = '胡志华' print(name) print(name) nulige() liuyang() print(name) huangwei()
黄伟
刘洋
刘洋
胡志华
黄伟
9.递归
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
import time person_list = ['Alex','Bob','Christian'] def ask_way(person_list): print('_'*60) if len(person_list) == 0: print('没有人知道') return '没有人知道' person = person_list.pop(0) if person == 'Christian': return '%s说:我知道,路在脚下' %person print('Hi,%s敢问路在何方?' %person) print('%s说:我不知道,我可以帮你去问问%s' %(person,person_list)) time.sleep(1) res = ask_way(person_list) print('%s问的结果是:%res' %(person, res)) return res res = ask_way(person_list) print(res)
____________________________________________________________ Hi,Alex敢问路在何方? Alex说:我不知道,我可以帮你去问问['Bob', 'Christian'] ____________________________________________________________ Hi,Bob敢问路在何方? Bob说:我不知道,我可以帮你去问问['Christian'] ____________________________________________________________ Bob问的结果是:'Christian说:我知道,路在脚下'es Alex问的结果是:'Christian说:我知道,路在脚下'es Christian说:我知道,路在脚下
def calc(n): print(n) if int(n/2) == 0: return n res = calc(int(n/2)) return res calc(10)
10 5 2 1
递归特性:
1. 必须有一个明确的结束条件
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,
每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,
所以,递归调用的次数过多,会导致栈溢出)
10.匿名函数
name = 'alex' def change_name(): return name+'sb' res=change_name() print(res) #改写为匿名函数 res=lambda x:x+'sb' print(res(name))
alexsb
alexsb
def calc(x): return x*x print(calc(10)) #改写成匿名函数 res = lambda x:x*x print(res(10))