函数进阶
函数参数 (function arguments)
形参分类 :
3. 动态传参 (万能)
def chi(*food):
print("我要吃", food)
chi("⼤⽶饭", "⼩⽶饭")
# 结果:
我要吃 ('⼤⽶饭', '⼩⽶饭') # 多个参数传递进去. 收到的内容是元组tuple
动态接收 位置参数 *args
- *args 位置参数的动态传参. 系统会自动的把所有的位置参数聚合成元组
- 在形参位置的 * 表示聚合
- 实参位置的 * 表示打散
- *args / *arguments
- 动态接收位置参数的时候要注意: 动态参数必须在位置参数后⾯
- 顺序: 位置参数 , , 默认值参数
def chi(a, b, *food):
print("我要吃", a, b, food)
chi("⼤⽶饭", "⼩⽶饭", "馒头", "⾯条")
# 前两个参数⽤位置参数来接收, 后⾯的参数⽤动态参数接收
# 打印结果 : 我要吃 大米饭 小米饭 ('馒头', '面条') # *food最后聚成元组
动态接收 关键字参数 **kwargs
- kwargs 关键字的动态传参 . 系统会自动把所有的关键字参数聚合成字典
- key word arguments 关键字参数
- 形参位置的 ** 表示聚合
- 实参位置的 ** 表示打散
def func(**kwargs):
print(kwargs)
func(a=1, b=2, c=3)
func(a=1, b=2)
结果:
{'a': 1, 'b': 2, 'c': 3} # **kwargs 最后聚合成dict
{'a': 1, 'b': 2}
def func(**kwargs):
print(*kwargs)
func(**{'a': 1, 'b': 2, 'c': 3})
# 打印结果是原字典的key
# a,b,c
打散
-
(*)在形参中聚合成元组 tuple
-
(**) 在形参中聚合成字典 dict
s1 = 'alex'
l1 = [1, 2, 3, 4]
tu1 = ('武sir', '太白', '女神',)
def func(*args):
print(args) # ('a', 'l', 'e', 'x', 1, 2, 3, 4, '武sir', '太白', '女神')
func(*s1,*l1,*tu1) # *在实参中, 结果是打散后组成新的元组
print(args) # ('alex', [1, 2, 3, 4], ('武sir', '太白', '女神'))
func(s1,l1,tu1) # *在形参中,打印结果是聚合成一个元组
print(*args) # 结果是 a l e x 1 2 3 4 武sir 太白 女神 (根据索引遍历一次)
func(*s1,*l1,*tu1)
魔性(*,**)
def foo(a, b, *args, c, sex=None, **kwargs):
print(a, b) # 1 ,2
print(c) # 12
print(sex) # 女
print(args) # (3,4)
print(kwargs) # {"name":"太白"}
foo(*[1, 2, 3, 4], **{'name': '太白', 'c': 12, 'sex': '女'}) # *或** 在实参处是打散数据(除int)
函数之外 * 用法 : (处理剩余元素)
- 类型必须是列表或元组
a,b,*c = [1,2,3,4,5,6]
print(a,b,c) # 1 2 [3,4,5,6] # 解包
a,*c,b = [1,2,3,4,5,6]
print(a,c,b) # 1 [2,3,4,5] 6
a,*c = range(5)
print(a,c) # 0 [1,2,3,4]
无敌传参
def func(*args, **kwargs): 无敌传参
最终顺序 :
位置参数 > *args > 默认值参数 > **kwargs
4.仅限关键字参数 (3.4版本之后新出)
位置 : 位置参数 > *args > 默认值参数 > 仅限关键字参数 > **kwargs
- 默认值参数 > 仅限关键字参数(没有特定要求,可互换位置)
- 只要在位置参数,*args之后,**kwargs之前就行
def func(a,b,*args,c,sex = "man",**kwargs): # c 仅限关键字参数
print(a)
print(b)
print(sex)
print(c)
print(args)
print(kwargs)
func(1,2,3,4,5,sex = "太光",c = 44,age = 22,name = "alex")
名称空间 :
全局命名空间 :
- 我们直接在py⽂件中, 函数外声明的变量都属于全局命名空间
局部命名空间 :
- 在函数中声明的变量会放在局部命名空间
内置命名空间 :
- 存放python解释器为我们提供的名字, list, tuple, str, int这些都是内置命名空间
加载顺序 : 内置 => 全局 => ( 函数执行时 ) 局部
取值顺序 : (就近原则)局部 => 全局 => 内置
作用域 :
- 作⽤域就是作⽤范围, 按照⽣效范围来看分为 全局作⽤域 和 局部作⽤域
- 变量或者函数的生命周期
全局作⽤域
- 包含内置命名空间和全局命名空间. 在整个⽂件的任何位置都可以使⽤(遵循从上到下逐⾏执⾏).
局部作⽤域 :
- 在函数内部可以使⽤.
作⽤域命名空间 :
全局作⽤域 : 全局命名空间 + 内置命名空间
局部作⽤域 : 局部命名空间
print(globals()) 查看全局作用域中的内容
print(locals()) 查看的是当前作用域中的内容
a = 10
def func():
a = 40
b = 20
def abc():
print("哈哈")
print(a, b) # 这⾥使⽤的是局部作⽤域
print(globals()) # 打印全局作⽤域中的内容
print(locals()) # 打印局部作⽤域中的内容
函数的嵌套 (高级函数)
关键字gloabal, nonlocal
global :
- 第一个功能:在局部作用域中可以更改全局作用域的变量
- 利用global在局部作用域也可以声明一个全局变量。
- 在局部作用域想要对全局作用域的全局变量进行修改时,需要用到 global(限于字符串,数字)。
nonlocal :
- 不能更改全局变量。
- 在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行和修改,并且引用的哪层,从那层及以下此变量全部发生改变。