https://www.cnblogs.com/linhaifeng/articles/6113086.html
——————————————————————————————————————
一、python中函数定义:
函数是逻辑结构化和过程化的一种编程方法。
python中函数定义方法:
def test(x):
"The function definitions"
x+=1
return x
def:定义函数的关键字
test:函数名
():内可定义形参
"":文档描述(非必要,但是强烈建议为你的函数添加描述信息)
x+=1:泛指代码块或程序处理逻辑
return:定义返回值
调用运行:可以带参数也可以不带
函数名()
'''
2*x+1
:param x:整形数字
:return: 返回计算结果
'''
def test(x):
y=2*x+1
return y
print(test)
a=test(1)
print(a)
运行结果:
<function test at 0x000001A32E0F1EA0> #test函数的内存地址
3
#无参函数
def test():
x=3
y=2*x+1
return y
a=test()
print(a)
运行结果:
7
——————————————————————————————————————
二、为何使用函数
现在老板让你写一个监控程序,监控服务器的系统状况,当cpu\memory\disk等指标的使用量超过阀值时即发邮件报警,你掏空了所有的知识量,写出了以下代码:
while True: if cpu利用率 > 90%: #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 if 硬盘使用空间 > 90%: #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 if 内存占用 > 80%: #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接
上面的代码实现了功能,但是:
1.代码重复过多,一个劲的copy and paste不符合高端程序员的气质
2.如果日后需要修改发邮件的这段代码,比如加入群发功能,那你就需要在所有用到这段代码的地方都修改一遍
优化后:
def 发送邮件(内容) #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 while True: if cpu利用率 > 90%: 发送邮件('CPU报警') if 硬盘使用空间 > 90%: 发送邮件('硬盘报警') if 内存占用 > 80%: 发送邮件('内存报警')
总结使用函数的好处:
1.代码重用
2.保持一致性,易维护
3.可扩展性
——————————————————————————————————————
三、函数和过程
#过程:就是没有返回值的函数
def test01(): msg = 'test01' print(msg) def test02(): msg = 'test02' print(msg) return msg def test03(): msg = 'test03' print(msg) return 1, 2, 3, 4, 'a', ['alex'], {'name': 'alex'}, None def test04(): msg = 'test04' print(msg) return {'name': 'alex'} t1 = test01() t2 = test02() t3 = test03() t4 = test04() print(t1) print(t2) print(t3) print(t4)
运行结果:
test01
test02
test03
test04
None
test02
(1, 2, 3, 4, 'a', ['alex'], {'name': 'alex'}, None)
{'name': 'alex'}
总结:当一个函数/过程没有使用return显示的定义返回值时,python解释器会隐式的返回None,
所以在python中即便是过程也可以算作函数。
返回值个数=0:返回None
返回值个数=1:返回object
返回值个数>1:返回tuple
——————————————————————————————————————
四、函数参数
1.形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量
2.实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值
def calc(x,y): #x,y形参
res=x**y
return res
c=calc(a,b) #a,b实参
print(c)
def test(x,y,z):#x=1,y=2,z=3
print(x)
print(y)
print(z)
3.位置参数,必须一一对应,缺一不行多一也不行
test(1,2,3)
关键字参数,无须一一对应,缺一不行多一也不行
test(y=1,x=3,z=4)
运行结果:
3
1
4
#位置参数必须在关键字参数左边
# test(1,y=2,3)#报错
# test(1,3,y=2)#报错
# test(1,3,z=2)
# test(1,3,z=2,y=4)#报错
# test(z=2,1,3)#报错
4.默认参数
def handle(x,type='mysql'):
print(x)
print(type)
handle('hello')
handle('hello',type='sqlite')
handle('hello','sqlite')
运行结果:
hello
mysql
hello
sqlite
hello
sqlite
5.参数组:**字典 *列表
def test(x,*args):
print(x)
print(args)
test(1)
test(1, 2, 3, 4, 5)
test(1, {'name': 'alex'})
test(1, ['x', 'y', 'z'])
test(1, *['x', 'y', 'z'])
test(1, *('x', 'y', 'z'))
运行结果:
1
()
1
(2, 3, 4, 5)
1
({'name': 'alex'},)
1
(['x', 'y', 'z'],)
1
('x', 'y', 'z')
1
('x', 'y', 'z')
def test(x,**kwargs):
print(x)
print(kwargs)
test(1,y=2,z=3)
运行结果:
1
{'y': 2, 'z': 3}
test(1,1,2,2,2,2,2,y=2,z=3) #报错,传的值多了
test(1,y=2,z=3,z=3)#会报错 :一个参数不能传两个值
def test(x,*args,**kwargs):
print(x)
print(args)
print(kwargs)
test(1,1,2,1,1,11,1,y=2,z=3)
运行结果:
1
(1, 2, 1, 1, 11, 1)
{'y': 2, 'z': 3}
def test(x,*args,**kwargs):
print(x)
print(args,args[-1])
print(kwargs,kwargs.get('y'))
test(1,*[1,2,3],**{'y':1})
运行结果:
1
(1, 2, 3) 3
{'y': 1} 1