基本介绍
优势:
1. 减少重复性代码;
2. 可读性高;
函数的定义与调用
常规函数
# 函数的定义
def login(): # def关键字 函数名():
pass # 函数体
# 函数的调用
login()
# return返回值
# 1. 当执行遇到return时,结束函数。
def func1():
print(111)
print(222)
return
print(333)
func1()
# 2. 给函数的调用者返回值
# a. 无return,返回None
# b. return不写或者None,返回None
# c. return返回单个数
# d. return返回多个数,将多个数存放在元祖中返回
函数的传参
# 函数的定义
def login(username,password): # 函数的定义(),存放的是形式参数,形参
pass
# 函数的调用
login("zhangsan","123") # 函数的执行(),存放的是实际参数,实参
#从实参角度
#1. 位置参数。必须一一对应,按顺序
def func1(x,y):
print(x,y)
func1(2,4) #即:x=2,y=4
func1(4,2) #即:x=4,y=2
#2. 关键字参数。必须一一对应,不分顺序
def func2(x,y,z):
print(x,y,z)
func2(x=1,z=3,y=2) #即:x=1,y=2,z=3
#3. 混合参数。一一对应,且关键字参数必须在位置参数后面
def func3(x,y,z):
print(x,y,z)
func3(1,2,z=3)# 注:当关键字在前时,如:func3(1,z=3,2) 报错: SyntaxError: positional argument follows keyword argument
#从形参角度
#1. 位置参数。必须一一对应,按顺序
def func1(x,y):
print(x,y)
func1(2,4) #即:x=2,y=4
func1(4,2) #即:x=4,y=2
#2. 默认参数。必须在位置参数后面
def func2(name, sex="男"):
pass
func2("张三")
#3. 动态参数。*args和**kwargs为万能参数。
def func3(*args, **kwargs): # 函数的定义 * 聚合。
print(args) # 元祖(所有位置参数)
print(kwargs) # 字典
l1 = [1,2,3]
t1 = (1,2,3)
func3(*l1, *t1) # 函数的执行, (1,2,3,1,2,3)
dic1 = {"name1": "张三"}
dic2 = {"name2": "李四"}
func3(**dic1, **dic2) # 函数的执行,{"name1": "张三", "name2": "李四"}
函数传参顺序:位置参数,*args,默认参数, **kwargs
进阶
- 临时名称空间:又名局部名称空间,存入函数里面的变量与值的关系,随着函数的执行结束,临时名称空间消失。
- 名称空间:分为全局名称空间,局部名称空间,内置名称空间
- 作用域:
全局作用域:全局名称空间,内置名称空间
局部作用域:局部名称空间- 加载顺序,取值顺序
加载顺序:内置名称空间–>全局名称空间–>局部名称空间(在函数执行时,才会加载到内存中)
取值顺序:局部名称空间(在函数执行时,才存在)–>全局名称空间–>内置名称空间globals() locals()
关键字:
global 1. 声明一个全局变量 2. 更改一个全局变量
nonlocal
函数名作用
1. 可以相互赋值
def func1():
print(111)
func2 = func1
func2()
2. 函数名可以当成函数的参数
def func1():
print(111)
def func2(args):
args()
print(222)
func2(func1)
3. 可以当成容器类数据类型的参数
def func1():
print(111)
def func2():
print(222)
def func3():
print(333)
l1 = [func1, func2,func3]
for i in l1
i()
4. 函数名可以当成函数的返回值
def func1():
print(666)
def func2(args):
print(777)
return args
ret = func2(func1)
ret()
闭包
内层函数对外层函数非全局变量的引用,叫做闭包。
好处:如果Python检测到闭包。有一个机制,局部作用域不会随着函数的结束而结束。
def wrapper()
name = 'zhangsan'
def inner():
print(name)
inner()
print(inner.__closure__) # 用于判断是否为闭包,不是返回None,是返回(<cell at 0x00000201186966A8: str object at 0x000002011872CF70>,)
wrapper()