函数的动态参数
动态接收位置参数(*args)
动态接收关键字参数(**kwargs)
def func(*args,**kwargs): print(args,kwargs) func("马化腾","马云",wtf="胡辣汤") #('马化腾', '马云') {'wtf': '胡辣汤'} 结果是一个tuple 和一个dict
#**********动态传参的另一种形式 def fun(*args): print(args) lst = [1,4,7] fun(lst[0],lst[1],lst[2]) #(1, 4, 7)
def fun(*args): print(args) lst = [1,4,7] fun(lst) #([1, 4, 7],) 直接传一个list进去的话,得到的就是一个元组
def fun(*args): print(args) lst = [1,4,7] fun(*lst) #(1, 4, 7) 用*把一个列表按顺序打散,得到的和按索引传的结果一样
def fun(*args): print(args) s="臣妾做不到" #字符串也可以打散(可迭代对象) fun(*s) #('臣', '妾', '做', '不', '到')
def func(*food): #
print(food) #(1, 2, 3, 4, 5, 6)
lst=[1,2,3,4,5,6]
func(*lst)
总结:在实参位置上给一个序列,列表,可迭代对象前面加上*表示把这个序列按照顺序打散
参数位置排列 (位置参数 *args 默认值参数 **kwargs)
函数的命名空间
代码在运行伊始,创建的存储“变量名与值的关系”的空间叫做全局命名空间;
在函数的运行中开辟的临时的空间叫做局部命名空间.
函数执行完毕后,函数内部变量占用的空间也会随着函数执行完毕而
命名空间有三种: 全局命名空间 局部命名空间 内置命名空间
*内置命名空间中存放了python解释器为我们提供的名字:input,print,str,list,tuple...它们都是我们熟悉的,拿过来就可以用的方法
*加载顺序: 内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)
a = 10 #全局命名空间的内容 def fn(): # fn也在全局命名空间 b = 20 #局部命名空间 print(a) def gn(): #全局命名空间 print(a) fn() gn()
作用域: 作用域就是作用范围, 按照生效的范围可以分为 全局作用域 和局部作用域
全局作用域 包含内置名称空间和全局名称空间
局部作用域 包含局部名称空间 只在局部范围内生效
a = 10 #全局命名空间的内容 def fn(): # 全局命名空间 a = 30 #局部命名空间 b = 20 #局部命名空间 def gn(): #局部命名空间 print("哈哈") print(a,b) print(globals()) #打印全局作用域中的内容 {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x012B73B0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/PycharmProjects/oldboy_2/day11/名称空间.py', '__cached__': None, 'a': 10, 'fn': <function fn at 0x013DC4B0>} print(locals()) #打印局部作用域中的内容 {'gn': <function fn.<locals>.gn at 0x013DC468>, 'b': 20, 'a': 30} fn()
嵌套函数
函数可以相互嵌套
#嵌套函数 def outer(): print("haha") def inner_1(): print("呵呵") def inner_1_1(): print("嘻嘻") inner_1_1() print("吼吼") def inner_2(): print("嘿嘿") inner_2() inner_1() outer() #haha #嘿嘿 #呵呵 #嘻嘻 #吼吼
global 和 nonlocal
global:
1,声明一个全局变量。
2,在局部作用域想要对全局作用域的全局变量进行修改时,需要用到 global(限于字符串,数字)
a = 100 def func(): global a # 加个global表示不在局部创建这个变量了,而是直接使用全局的a a = 28 print(a) #28 func() print(a) #28
ps:对可变数据类型(list,dict,set)可以直接引用不用通过global。
lst = ["马化腾","刘嘉玲","詹姆斯"] def func(): lst.append("马云") #对于可变数据类型可以访问,但是不能赋值(针对字符串和数字而言) print(lst) #['马化腾', '刘嘉玲', '詹姆斯', '马云'] func() print(lst) #['马化腾', '刘嘉玲', '詹姆斯', '马云']
nonlocal:
1,不能修改全局变量。
2,在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。
#对比一下有nonlocal 和 没有nonlocal a = 10 def func1(): a = 20 def func2(): nonlocal a #有nonlocal 当func2()执行完毕的时候,a的值从函数中跳出,指向def func2()外层的a a = 30 print(a)#30 func2() print(a)#30 func1() a = 10 def func1(): a = 20 def func2(): a = 30 print(a)#30 #没有nonlocal 在func2()跳出循环的时候,a的值从函数中跳出时指向函数外层的 a=20 func2() print(a)#20 func1()
a = 10 def outer(): a = 30 def inner(): # 在inner中改变a的值, 寻找外层函数中离他最近的那个变量 nonlocal a a = 20 print(a) #20 inner() print(a)#20 outer() print(a)#10