形参:
1.位置传参 2. 默认值传参. 3.动态传参
一 动态传参(形参的一种):
之前我们说过了了传参, 如果我们需要给⼀一个函数传参, ⽽而参数⼜又是不确定的. 或者我给⼀一个
函数传很多参数, 我的形参就要写很多, 很⿇麻烦, 怎么办呢. 我们可以考虑使⽤用动态参数.
动态传参分两种:
(1) 动态接收位置参数和默认值参数
def chi(*food):# *表⽰示接收任意内容 print("我要吃", food) chi("⼤大⽶米饭", "⼩小⽶米饭") 结果: 我要吃 ('⼤大⽶米饭', '⼩小⽶米饭') # 多个参数传递进去. 收到的内容是元组tuple
需要注意的是 : 动态参数必须在位置参数后⾯ 例如:
def chi(*food, a, b): print("我要吃", food, a, b) chi("⼤大⽶米饭", "⼩小⽶米饭", "⻩黄⽠瓜", "茄⼦子")
这时程序运⾏行行会报错. 因为前⾯面传递进去的所有位置参数都被*food接收了了. a和b永远接收
不到参数
所以必须改写成以下代码:
def chi(*food, a, b): print("我要吃", food, a, b) chi("⼤大⽶米饭", "⼩小⽶米饭", a="⻩黄⽠瓜", b="茄⼦子") # 必须⽤用关键字参数来指定
这个时候a和b就有值了了, 但是这样写呢位置参数就不能⽤用了了. 所以. 我们要先写位置参数,
def chi(a, b, *food): print("我要吃", a, b, food) chi("⼤大⽶米饭", "⼩小⽶米饭", "馒头", "⾯面条") # 前两个参数用位置参数来接收, 后⾯面的参数⽤动态参数 动态参数接收
默认值参数
def chi(a, b, c='馒头', *food): print(a, b, c, food) chi("⾹香蕉", "菠萝") # ⾹香蕉 菠萝 馒头 (). 默认值⽣生效 chi("⾹香蕉", "菠萝", "葫芦娃") # ⾹香蕉 菠萝 葫芦娃 () 默认值不不⽣生效 chi("⾹香蕉", "菠萝", "葫芦娃", "口罩") # ⾹香蕉 菠萝 葫芦娃 ('口罩',) 默认值不不⽣生效
默认值参数写在动态参数前⾯面. 默认值只有一种情况可能会⽣生效
例子:
def chi(a, b, *food, c="娃哈哈"): #在这里. 其实相当于把传进来的参数做了一次聚合, 聚合成一个元组
print(a, b, food, c)
chi("⾹香蕉", "菠萝") # ⾹香蕉 菠萝 () 娃哈哈 默认值⽣生效
chi("⾹香蕉", "菠萝", "葫芦娃") # ⾹香蕉 菠萝 ('葫芦娃',) 娃哈哈 默认值⽣生效
chi("⾹香蕉", "菠萝", "葫芦娃", "⼝口罩") # ⾹香蕉 菠萝 ('葫芦娃', '⼝口罩') 娃哈哈 默 认值生效
这么写就生效了 这个时候如果不给出关键字传参. 那么你的默
认值是永远都⽣生效的
所以得到结论 :
默认值.位置传参和动态传参的顺序为:位置 动态 默认值参数
(2)关键字传参
在python中使⽤用**来接收动态关键字参数
def func(**kwargs): print(kwargs) func(a=1, b=2, c=3) func(a=1, b=2) 结果: {'a': 1, 'b': 2, 'c': 3} {'a': 1, 'b': 2} 这个时候接收的是⼀一个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) # print(kwargs) # # func(1, 2, 5, jj="陶喆", jay="zhoujielun", soup="胡辣汤")
结果为:(1, 2, 5)
{'jj': '陶喆', 'jay': 'zhoujielun', 'soup': '胡辣汤'}
* 和**出现在实参上时
拿个例子来说
def func(*args): print(args) lst = "娃哈哈" func(*lst) 结果('娃', '哈', '哈') # 在实参位置 * 表示打散, 打散的是可迭代对象
def func( **kwargs):
print(kwargs)
dic = {"2": "明教教主", "谢逊": "金毛狮王", "范瑶": "光明右使"}
##func(张无忌=dic['张无忌'], 谢逊=dic['谢逊'], 范瑶=dic['范瑶'])
func(**dic) 结果: {'2': '明教教主', '谢逊': '金毛狮王', '范瑶': '光明右使'}
# 这里的** 是把字典打散. 字典的key作为参数的名字, 字典的值作为参数的值传递给形参
小结:
1. *args 位置参数的动态传参. 系统会自动的把所有的位置参数聚合成元组
# 2. **kwargs 关键字的动态传参. 系统会自动把所有的关键字参数聚合成字典
# 3. def func(*args, **kwargs): 无敌传参
# 4. 顺序: 位置参数, *args, 默认值, **kwargs
# 5. 在使用的时候, 可以任意的进行搭配
# 4. 在实参上. *, **表示的打散. 在形参. *,** 表示聚合
二 命名空间
1.名称空间
内置空间 ::存放python解释器为我们提供的名字, list, tuple, str, int这些都是内置空间
全局空间: :我们直接在py⽂文件中, 函数外声明的变量量都属于全局命名空间
局部空间 : ;在函数中声明的变量量会放在局部命名空间
加载顺序:
1. 内置命名空间
2. 全局命名空间
3. 局部命名空间(函数被执⾏行行的时候)
最开始会开辟一个自己的命名空间- 内置名称空间
a = 10 # 全局 # def func(): # # a = 20# 局部 # print(a)#局部 # # func()
取值顺序:
局部 => 全局 => 内置
三 作用域(变量或者函数的声明周期)
作⽤用域就是作⽤用范围, 按照⽣生效范围来看分为 全局作⽤用域和局部作⽤用域
全局作⽤用域: 包含内置命名空间和全局命名空间. 在整个⽂文件的任何位置都可以使⽤用(遵循
从上到下逐⾏行行执⾏行行). 局部作⽤用域: 在函数内部可以使⽤用.
全局作用域: 全局名称空间+内置名称空
局部作用域: 局部名称空间
1.我们可以通过globals()函数来查看全局作⽤用域中的内容, 也可以通过locals()来查看局部作
⽤用域中的变量量和函数信息
1. globals() 查看全局作用域中的所有内容
# qiao = "乔峰"
# def 抗收音机():
# bgm = "难念的经"
# print("娃哈哈")
# print(locals())
# 抗收音机() #
print(globals()) ## 查看全局作用域中的内容
print(locals()) # locals()查看的是当前作用域中的内容
四 函数的嵌套
1. 只要遇⻅见了了()就是函数的调用. 如果没有()就不是函数的调⽤
def func1(): # print("我是func1") # # def func2(): # print("我是func2") # func1() # # def func3(): # func2() # print("我是func3") # func3() # 这样的代码不是嵌套. 互相调用
2. 函数的执行顺序
简单的嵌套 例子1
ef outer(): # def inner(): # print("我是内部") # print("我是外部") # inner() # # outer()
例子2
ef outer(): # print("我是外面的") # def inner_1(): # def inner_2(): # print("我是里面的2") # inner_2() # print("我是里面的1") # inner_1() # print("我是外面的收尾") # # outer()
3.关键字global和nonlocal
首先在全局声明一个变量, 然后再局部调用这个变量, 并改变这
个变量的值
global表示. 不再使用局部作用域中的内容了. 而改用全局作用域中的变量
a = 100 def func(): global a # 加了了个global表示不再局部创建这个变量了. 而是直接使用全局的a 把全局的变成和局部一样的变量 a = 28 print(a) func() print(a)
a = 10 # def func(): # global a #表示在当前作用域中的使用的a是全局中的变量 # a = 20 # 所有的a都是外面的了 # print(a) # 现在只有看的权利 #
例子2
lst = ["麻花藤", "刘嘉玲", "詹姆斯"]
def func(): lst.append("⻢马云云") # 对于可变数据类型可以直接进⾏行行访问. 但是不不能改地址. 说⽩白 了了. 不不能赋值 print(lst) func() print(lst)
nonlocal(找的是局部当中, 离他最近的上层的那个变量)
def outer(): # a = 10 # def inner(): # nonlocal a # 找的是局部当中, 离他最近的上层的那个变量 # a = 20 # print(a) # print(a) # 10 # inner() # 20 # print(a) # 20 # outer()
global 引入全局变量, 可以定义全局变量
nonlocal 引入局部中离他最近的外层变量
def func(): global a # 没有也得有. 自动帮你创建 # 定义全局变量 a = 20 func() print(a)