Python 函数
函数的定义及调用
函数的作用:增强代码的重用性和可读性。
函数的定义与调用:
-
- def:表示函数的关键字
- 函数名:函数的名称,日后根据函数名调用函数
- 函数体:函数中进行一系列的逻辑计算,如:发送邮件、计算出 [11,22,38,888,2]中的最大数等...
- 参数:为函数体提供数据
- 返回值:当函数执行完毕后,可以给调用者返回数据。
1 def 函数名(参数):
2
3 ...
4 函数体
5 ...
调用:函数名()
返回值:
返回值有几种情况:分别是没有返回值、返回一个值、返回多个值
没有返回值(返回None):
不写return
return None
只写return
返回一个值:
return后面写上要返回的内容。
返回多个值:
可以返回任意多个、任意数据类型的值。
返回的多个值会被组织成元组被返回,也可以用多个值来接收
def ret_demo2():
return 1,['a','b'],3,4
#返回多个值,用一个变量接收
ret2 = ret_demo2()
print(ret2)
#返回多个值,用多个变量接收
a,b,c,d = ret_demo2()
print(a,b,c,d)
#用多个值接收返回值:返回几个值,就用几个变量接收
a,b,c,d = ret_demo2()
print(a,b,c,d)
参数:
形参:函数定义时定义的值。
位置参数
def mymax(x,y):
#此时x = 10,y = 20
print(x,y)
the_max = x if x > y else y
return the_max
#调用mymax不传递参数
ma = mymax()
print(ma)
#结果
TypeError: mymax() missing 2 required positional arguments: 'x' and 'y'
默认参数
def stu_info(name,sex = "male"):
"""打印学生信息函数,由于班中大部分学生都是男生,
所以设置默认参数sex的默认值为'male'
"""
print(name,sex)
stu_info('alex')
stu_info('eva','female')
动态参数:
*args
def stu_info(**kwargs):
print(kwargs)
print(kwargs['name'],kwargs['sex'])
stu_info(name = 'alex',sex = 'male')
**kwargs
实参:函数调用时传入的值。
按位置传值
按关键字传值
函数进阶
命名空间和作用域
命名空间的本质:存放名字与值的绑定关系
命名空间一共分为三种:
全局命名空间
局部命名空间
内置命名空间
*内置命名空间中存放了python解释器为我们提供的名字:input,print,str,list,tuple...它们都是我们熟悉的,拿过来就可以用的方法。
三种命名空间之间的加载与取值顺序:
加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)
取值:在局部调用:局部命名空间->全局命名空间->内置命名空间
作用域
作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。
全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效
局部作用域:局部名称空间,只能在局部范围内生效
函数的嵌套和作用域链
函数的嵌套调用
def max2(x,y): m = x if x>y else y return m def max4(a,b,c,d): res1 = max2(a,b) res2 = max2(res1,c) res3 = max2(res2,d) return res3 # max4(23,-7,31,11)
函数名的本质
函数名本质上就是函数的内存地址
1.可以被引用
2.可以被当作容器类型的元素
3.可以当作函数的参数和返回值
闭包
def func():
name = 'eva'
def inner():
print(name)
闭包函数:
内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数
#函数内部定义的函数称为内部函数
def func():
name = 'eva'
def inner():
print(name)
return inner
f = func()
f()
判断闭包函数的方法__closure__
#输出的__closure__有cell元素 :是闭包函数
def func():
name = 'eva'
def inner():
print(name)
print(inner.__closure__)
return inner
f = func()
f()
#输出的__closure__为None :不是闭包函数
name = 'egon'
def func2():
def inner():
print(name)
print(inner.__closure__)
return inner
f2 = func2()
f2()
本章小结
命名空间:
一共有三种命名空间从大范围到小范围的顺序:内置命名空间、全局命名空间、局部命名空间
作用域(包括函数的作用域链):
小范围的可以用大范围的
但是大范围的不能用小范围的
范围从大到小(图)
在小范围内,如果要用一个变量,是当前这个小范围有的,就用自己的
如果在小范围内没有,就用上一级的,上一级没有就用上上一级的,以此类推。
如果都没有,报错
函数的嵌套:
嵌套调用
嵌套定义:定义在内部的函数无法直接在全局被调用
函数名的本质:
就是一个变量,保存了函数所在的内存地址
闭包:
内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数
装饰器
装饰器的固定格式:
def timer(func): def inner(*args,**kwargs): '''执行函数之前要做的''' re = func(*args,**kwargs) '''执行函数之后要做的''' return re return inner
带参数的装饰器:
def outer(flag): def timer(func): def inner(*args,**kwargs): if flag: print('''执行函数之前要做的''') re = func(*args,**kwargs) if flag: print('''执行函数之后要做的''') return re return inner return timer @outer(False) def func(): print(111) func()
多个装饰器装饰同一个函数
def wrapper1(func): def inner(): print('wrapper1 ,before func') func() print('wrapper1 ,after func') return inner def wrapper2(func): def inner(): print('wrapper2 ,before func') func() print('wrapper2 ,after func') return inner @wrapper2 @wrapper1 def f(): print('in f') f()