动态传参,命名空间,嵌套,gloabal,nonlocal
一、动态传参
动态接受位置参数: *参数名
def eat(*food): print(food) #多个参数传递进去,收到的内容是元祖tuple eat("盖浇饭", "麻辣烫", "冰封") #('盖浇饭', '麻辣烫', '冰封')
动态接收参数的时候要注意,动态参数必须在位置参数后面
错误事例:
# def eat(*food, a, b): # print(food, a, b) # eat("盖浇饭", "麻辣烫", "冰封") #程序会报错,因为传递进去的位置参数都被*food接收了,a和b永远接收不到参数
正确事例:
# def eat(a, b, *food): # print(a, b, food) # eat("盖浇饭", "麻辣烫", "冰封") #盖浇饭 麻辣烫 ('冰封',) #前两个参数用位置参数接收,后面的参数用动态参数接收
默认值参数写在动态参数前面,默认值只有一种情况可能会生效
# def eat(a, b, c='馒头', *food): # print(a, b, c, food) # eat("盖浇饭", "麻辣烫") #盖浇饭 麻辣烫 馒头 () 默认值生效 # eat("盖浇饭", "麻辣烫", "冰封") #盖浇饭 麻辣烫 冰封 () # eat("盖浇饭", "麻辣烫", "冰封", "烧烤") #盖浇饭 麻辣烫 冰封 (‘烧烤’,)
默认值参数写在动态参数后面,所有的默认值都生效
# def eat(a, b, *food, c='馒头'): # print(a, b, food, c) # eat("盖浇饭", "麻辣烫") #盖浇饭 麻辣烫 () 馒头 默认值生效 # eat("盖浇饭", "麻辣烫", "冰封") #盖浇饭 麻辣烫 ('冰封',) 馒头 默认值生效 # eat("盖浇饭", "麻辣烫", "冰封", "烧烤") #盖浇饭 麻辣烫 ('冰封', '烧烤') 馒头 默认值生效
动态参数接收关键字参数: **参数名
# def eat(**food): # **关键字参数 # print(food) 'good_food': '盖浇饭', 'junk_food': '麻辣烫', 'drink': '脉动'} # eat(good_food='盖浇饭', junk_food="麻辣烫", drink="脉动") 参数传递进去,收到的内容是字典dict
关键字参数必须要在位置参数后面,否则报错
def func(a, b, c, d): print(a, b, c, d) func(1, 2, c=3, 4) #报错
最终顺序:位置参数 > *args > 默认值参数 > **kwargs
接收所有的参数
# def func(*args, **kwargs): # print(args, kwargs) # func(1, 4, a=8, b = 9, c= 10) (1, 4) {'a': 8, 'b': 9, 'c': 10}
动态参数的另一种传参方式
# def eat(*fruit): # 聚合成元组 # print(fruit) # lst = ["香蕉", "茄子", "黄瓜", "辣椒", "大白梨"] # eat(lst[0], lst[1], lst[2], lst[3], lst[4]) ('香蕉', '茄子', '黄瓜', '辣椒', '大白梨') # eat(*lst) # 这里的*表示的是把lst打散 ('香蕉', '茄子', '黄瓜', '辣椒', '大白梨')
def fun(*args): print(args) s = '臣妾做不到'(可迭代对象) fun(*s) #('臣', '妾', '做', '不', '到') 以最小单元为元素,输出元祖
字典打散,聚合,还是字典
def fun(**kwargs): print(kwargs) dic = {'a':1,'b':2} fun(**dic) #{'a': 1, 'b': 2}
二、命名空间
命名空间一共分为三种:
全局命名空间:我们直接在py文件中,函数外声明的变量都属于全局命名空间
局部命名空间:在函数中声明的变量会放在局部命名空间
内置命名空间:存放了python解释器为我们提供的名字:input,print,str,list,tuple..都是内置命名空间
三种命名空间之间的加载与取值顺序:
加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)
取值顺序:
在局部调用:局部命名空间->全局命名空间->内置命名空间
在全局调用:全局命名空间->内置命名空间
综上所述,在找寻变量时,从小范围,一层一层到大范围去找寻。
作用域:作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。
全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效
局部作用域:局部名称空间,只能在局部范围内生效
a = 10 # 全局 def func(): # 全局 a = 40 # 局部 b = 20 # 局部
func() # 全局
# print(globals()) # 打印全局作用域中的内容 # print(locals()) # 打印局部作用域中的内容
三、函数嵌套
目前为止,所有的()表示的就是函数的调用
def f1(): print(111)
def f2(): print(222) f2() f1() #111 222
四、global和nonlocal
global: 寻找全局作用域中的内容
nonlocal: 寻找上一级作用域中的内容, 但不能是全局的
# a = 10 # def func(): # global a # 加了个global表示不在局部创建这个变量,直接使用全局的a # a = 20 # print(a) # func() # print(a)
a = 10 def func1(): a = 20 print(a) def fun2(): nonlocal a # 调用上一级的变量, 且不能是全局 a = 30 print(a) fun2() print(a) func1() print(a)