今日内容
函数参数之位置参数
位置形参
函数定义阶段括号内从左往右依次填写变量名
def func1(a, b, c):pass
位置实参
函数调用阶段依次从左往右填写的数据值
func1(1, 2, 3)
代码案例理解:
def func1(a, b):
print(a,b)
func1(1, 2) # 1,2 按照位置从左到右一一对应传值
func1(1) # 必须都要有对应的值,少一个不行,直接报错
func1(1, 2, 3) # 多一个也不行,直接报错
func1(a=1, b=2) # 可以指名道姓的传 a传1 b传2
func1(b=1, 2) # 关键字传参一定要跟在位置传参后面 报错
func1(2, b=1) # 这是可以的因为他跟着位置传参后面
func1(1, a=2, b=3)
# 同一个参数在调用的情况下不能多次赋值 直接报错
# 上述1已经赋值给a了 然后2又赋值给a这是不可以的
name = 'jason'
pwd = 123
# func1(name, pwd) # 实参没有固定的定义 可以传数据值 也可以传绑定了数据值的变量名
func1(a=name, b=pwd) # 实参没有固定的定义 可以传数据值 也可以传绑定了数据值的变量名
越短越简单的靠前越长越复杂的靠后
默认参数
在定义函数时,就已经为形参赋值,这类形参称之为默认参数,当函数有多个参数时,需要将值经常改变的参数定义成位置参数,而将值改变较少的参数定义成默认参数
def register(name, age, sex='male'): # 默认sex为male
print('''
```````学生信息`````````
姓名:{name}
年龄:{age}
性别:{sex}
```````````````````````
''')
register('jason', 18)
register('kevin', 28)
register('lili', 28, 'female')
register('lili', 28, sex='female')
# 性别会自动显示male 可以手动修改
可变长形参
参数的长度可变指的是在调用函数时,实参的个数可以不固定,而在调用函数时,实参的定义无非是按位置或者按关键字两种形式,这就要求形参提供两种解决方案来分别处理两种形式的可变长度的参数
def func1(*a):
print(a)
func1() # ()
func1(1) # (1,)
func1(1,2) # (1, 2)
def func2(b, *a):
print(a, b)
func2() # 函数至少需要一个参数给b
func2(1) # () 1
func2(1, 2, 3, 4) # 实参1按照位置给b赋值 多余的234则被*号吸收然后以元组的形式保存赋值给a
'''
*号在实参中用于接收多余的位置参数,然后组成元组赋值给*号后面的变量名
'''
def func3(**k):
print(k)
func3() # {} 字典形式
func3(a=1) # {'a': 1}
func3(a=1,b=2,c=3) # {'a' : 1, 'b' : 2, 'c' : 3}
def func4(a, **k):
print(a, k)
func4() # 函数至少需要一个参数给到a
func4(a=1) # 1 {}
func4(a=1, b=2, c=3) # 1 {'b': 2, 'c': 3}
func4(a=1, b=2, c=3, x='jason', y='kevin') # 1 {'b': 2, 'c': 3, 'x': 'jason', 'y': 'kevin'}
# 应关键字参数1 然后多余的被**吸收转成字典的形式赋值给**后面的变量名
def func5(n, *a, **k):
print(n, a, k)
func5(1, 2, 3) # 1 (2, 3) {} 1赋值给n 2和3赋值给a并且转成元组 代码中没有关键字参数所以为空
func5(n=1, a=2, c=3) # 1 () {'a': 2, 'c': 3}
# 1赋值给n a没有适合自己的赋值为空 剩下的ac关键字参数转成字典赋值给k
func5(1, 2, 3, a=1, b=2, c=3)
# 1 (2, 3) {'a': 1, 'b': 2, 'c': 3}
# 1赋值给n 23转元组赋值给a 剩下的是关键字参数全部转字典赋值给k
'''
由于*和**在函数的形参中使用频率很高 后面跟的变量名推荐使用
*args
**kwargs
def index(*args,**kwargs):pass
"""
可变长实参
def index(a, b, c):
print(a, b, c)
l1 = [11, 22, 33]
t1 = (33, 22, 11)
s1 = 'jon'
se = {123, 321, 222}
d1 = {'username': 'jason', 'pwd': 123, 'age': 18}
index(*l1) # 11 22 33 把列表拿走了传出里面的数据值
index(*t1) # 33 22 11 把元组拿走了传出数据值
index(*s1) # j o n jon 拆开一一对应abc
index(*se) # 321 123 222 字典去掉,一一对应abc 但是是无序排列
index(*d1) # username pwd age 只会取键对应abc
"""
*在实参中
类似于for循环 将所有循环遍历出来的数据按照位置参数一次性传给函数
"""
def index(username, pwd, age):
print(username, pwd, age)
d1 = {'username': 'jason', 'pwd': 123, 'age': 18}
index(**d1)
# index(username='jason',pwd=123,age=18)
# 取键值 对应username pwd age
"""
**在实参中
将字典打散成关键字参数的形式传递给函数
"""
def index(*args, **kwargs):
print(args) # (11, 22, 33, 44)
print(kwargs) # {}
index(*[11, 22, 33, 44]) # index(11, 22, 33, 44)
# 多余的位置参数被*号吸收转成元组
命名关键字参数(适当了解)
'''形参必须按照关键字参数传值>>>:命名关键字参数'''
def index(name, *args, gender='male', **kwargs):
print(name, args, gender, kwargs)
# index('jason',1,2,3,4,a=1,b=2)
index('jason', 1, 2, 3, 4, 'female', b=2)
名称空间
名称空间就是储存变量名的地方
1.内置名称空间
#py解释器当中的名字
系统自带的空间,里面存储了很多关键字和变量名
2.全局名称空间
#运行py文件产生的空间
py文件运行产生,里面存放文件级别的名字()
模块名、变量名、函数名、类名
3.局部名称空间 # 运行函数时产生的空间
函数体代码运行、类体代码 产生的空间
名称空间存活周期及作用范围(域)
存活周期
内置名称空间
python解释器启动则创建 关闭则销毁
全局名称空间
py文件执行则创建 运行结束则销毁
局部名称空间
函数体代码运行创建 函数体代码结束则销毁(类暂且不考虑)
作用域
内置名称空间
解释器级别的全局有效
全局名称空间
py文件级别的全局有效
局部名称空间
函数体代码内有效
名字的查找顺序
名字的查找一定要先清除自己在哪个空间
1.当我们在局部空间的时候
局部>>全局>>内置
2.当我们在全局空间的时候
全局>>内置
可以从里到外,不能从外到里
名字的查找顺序可以打破
查找顺序案例
1.相互独立的局部名称空间默认不能够互相访问
def func1():
name = 'jason'
print(age)
def func2():
age = 18
print(name)
2.局部名称空间嵌套
先从自己的局部名称空间查找 之后由内而外依次查找
函数体代码中名字的查找顺序在函数定义阶段就已经固定死了
x = '干饭了' # 全局空间里的x绑定 干饭了
def func1():
x = 1
def func2():
x = 2
def func3():
print(x) # 定义阶段就知道func3定义阶段没有等x
x = 3
func3()
func2()
func1()
'其实是由四个x,并不是替换'
函数在定义阶段名字查找顺序就已经定死了
作业
money = 100
def index():
money = 666
print(money)
# 会打印出100,因为函数体代码根本就木有运行所以直接100
money = 100
def func1():
money = 666
def func2():
money = 888
func2()
print(money)
# 会打印出100,因为函数体代码根本就木有运行所以直接100
标签:index,func1,函数,参数,print,def,赋值
From: https://www.cnblogs.com/lsl1/p/16777320.html