函数参数、名称空间与作用域、名字的查找顺序
目录一、函数参数
1.形参与实参
1.形式参数
在函数定义阶段括号内填写的参数,简称'形参'
2.实际参数
在函数调用阶段括号内填写的参数,简称'实参'
形参与实参的关系:
形参类似于变量名,在函数定义阶段可以随便写,最好知名见意
eg:
def register(name, pwd):
pass
实参类似于数据值,在函数调用阶段与形参临时绑定,函数运行结束立刻断开
eg:
register('jason', 123) 形参name与jason绑定,形参pwd与123绑定
eg:
def register(name, pwd):
print(name,pwd)
register('jason', 123)
2.位置参数
1.位置形参
在函数定义阶段括号内从左到右依次填写的变量名
def func(a, b, c):pass # 当代码只有一行的情况下,可以直接在冒号后编写,不用换行
2.位置实参
在函数调用阶段括号内从左到右依次填写的数据值
eg:
def func(a, b,c):
print(a,b,c)
func(1,2,3) # 1 2 3
name = 'jason'
func(name,1,2) # jason 1 2
# 实参必须要与形参的个数一一对应(个数一致),不能多也不能少
eg:
def func(a, b):
print(a,b)
func(1,2) # 1,2
func(1) # 报错,少一个不行,多一个也不行
func(b=1,a=2) # 关键字传参(指名道姓的传)
func(b=2,1) # 报错,关键字传参一定要跟在位置传参的后面
func(3,b=9) # 可以
func(1,a=2,b=7) # 报错,同一个形参在调用的时候不能多次赋值
eg:
def func(a,b):
print(a,b)
name = 'jason'
pwd = 123
func(name,pwd) # jason 123
func(a=name, b=pwd) # 实参没有固定的含义,可以传数据值,也可以传绑定了数据值的变量名
3.关键字参数
1.关键字实参,给函数传值时指定参数名
2.关键字参数指调用阶段,括号内什么等于什么的形式传值,比如a=name,b=pwd
3.注意位置实参必须在关键字参数的前面
4.无论是实参函数形参,遵循简单的在前,复杂的在后,同一个形参在调用的时候不能多次赋值
eg:
def func(a,b,c):
print(a,b,c)
func(1,a=3,b=6) # 报错,同一个形参不能多次赋值
4.默认参数
默认参数的本质就是关键字形参,别名默认参数,提前已经给了,用户可以不传,也可以传
eg:
def register(name,age,gender = 'male'):
print(f'''
name:{name}
age:{age}
gender:{gender}
''')
register('jason',12) # name:jason age:12 gender:male
register('jia',11,'female') # name:jason age:12 gender:female
# 自定义阶段,后续调用不用传值,如果自己传值的话,则后续用自己写的值
5.可变长形参
1.*在形参中的应用
eg:
def func(*a):
print(a)
func() # ()
func(1) # (1,)
func(2,4) # (2, 4)
# *在形参中用于接收多余的位置参数,组织成元组赋值给*后面的变量名
eg:
def func(c,*a):
print(a,c)
func() # 报错,至少有一个参数给到c
func(1) # () 1
func(2,4) # (4,) 2
2.**在形参中的应用 # {'a': 2, 'b': 8, 'c': 9}
eg:
def func(**k):
print(k)
func() # {}
func(a=1) # {'a': 1}
func(a=2,b=8,c=9)
# **在形参中,用于接收多余的关键字参数,组织成字典赋值给**后面的变量名
eg:
def func(a,**k):
print(k)
func() # 报错,至少有一个参数给到a
func(a=1) # 1 {}
func(a=2,b=8,c=9) # 2 {'b': 8, 'c': 9}
3.*和**在形参中的混合应用
eg:
def func(*args,**kwargs):
print(args,kwargs)
func() # () {}
func(1,2,3) # (1, 2, 3) {}
func(a=1,b=4,c=6) # () {'a': 1, 'b': 4, 'c': 6}
func(1,2,3,a=3,b=5,c=8) # (1, 2, 3) {'a': 3, 'b': 5, 'c': 8}
'''
*和**在函数的形参中的使用频率很高的,推荐使用下面这种:
*args
**kwargs
def index(*args,**kwargs):pass
'''
6.可变长实参
eg:
def index(a,b,c):
print(a,b,c)
l1 = [1,2,3]
t1 = {1,2,3}
f1 = (22,34,66)
p1 = 'jas'
k1 = {'name':'name','pwd':123,'age':19}
index(*l1) # 1 2 3
index(*t1) # 1 2 3
index(*f1) # 22 34 66
index(*p1) # j a s
index(*k1) # name pwd age
# 将列表,集合,元组,字符串,字典中的三个值,取出来传给函数的三个形参(写得时候注意个数,博客少写或者多写)
#这种方法类似于for循环,将所有循环遍历出来得数据按照位置参数一次性穿给函数
7.命名关键字参数(了解)
形参必须按照关键字参数传参:命名关键字参数
eg:
def index(name,*args,gender='male',**kwargs):
print(name,args,gender,kwargs)
index('jason',1,2,3,'female',b=3,h=8)
# jason (1, 2, 3, 'female') male {'b': 3, 'h': 8}
二、名称空间
eg:
name = 'jason'
# 1.申请一个内存空间存储jason
# 2.给jason绑定一个变量名name
# 3.后续通过name就可以访问到jason了
名称空间就是用来存储变量名与数据值绑定关系的地方(存储变量名的地方)
1.内置名称空间
解释器运行自动产生的,可直接使用的方法名字都在里面
eg: len print input
2.全局名称空间
py文件运行产生的,里面存放文件级别的名字
eg:
name = 'jason'
eg: if name ='jason':
age = 18
eg: while True:
gender='male'
eg: def index();
pass
# 上述的name,age,gender,index都是存放文件级别的名字
3.局部名称空间
函数体代码运行/类体代码运行 产生的空间
三、作用域
作用域:
1.内置名称空间
解释器级别的全局有效
2.全局名称空间
py文件级别的全局有效
3.局部名称空间
函数体代码内有效
存活周期:
1.内置名称
解释器启动则创建,关闭则销毁
2.全局名称空间
py文件执行则创建,运行结束则销毁
3.局部名称空间
函数体代码运行创建,函数体代码结束运行则销毁
名称空间 | 作用域 | 存活周期 |
---|---|---|
内置名称空间 | 解释器级别的全局有效 | 解释器启动则创建,关闭则销毁 |
全局名称空间 | py文件级别的全局有效 | py文件执行则创建,运行结束则销毁 |
局部名称空间 | 函数体代码内有效 | 函数体代码运行创建,函数体代码结束运行则销毁 |
四、名字的查找顺序
涉及到名字的查找的时候,一定要明白自己在哪个空间
1.当我们在局部名称空间的时候
局部名称空间>>>全局名称空间>>>内置名称空间
eg:
len = '我是全局名称空间的len'
def index():
len = '我是局部名称空间的len'
print(len)
index() # 我是局部名称空间的len
2.当我们在全局名称空间的时候
全局名称空间>>>内置名称空间
五、查找顺序案例
1.互相独立的局部名称空间默认不能相互访问
eg:
def func():
name='jason'
print(age)
2.局部名称空间嵌套
从局部名称空间开始查找,由内而外依次查找
六、作业
判断下列money的值是多少并说明理由 思考如何修改而不是新增绑定关系
money = 100
def index():
money = 666
print(money) # 100
money = 100
def func1():
money = 666
def func2():
money = 888
func2()
print(money) # 100 全局money打印出来得
标签:jason,name,作用域,eg,函数参数,查找,func,print,def
From: https://www.cnblogs.com/zx0524/p/16776809.html