函数的参数
目录
参数是函数的精髓
一、形参与实参介绍
函数的参数两大分类分为形式参数和实际参数,简称形参和实参
形参即在函数定义阶段,括号内填入的变量名,用于接收外部传来的值
实参即在调用阶段,括号内传入的数据值。数据值可以是常量、变量、函数的返回值。
def my_func(a, b):
pass
# 此时,a,b就是函数my_func的形参
my_func(1,2)
# 此时,数据1,2就是函数my_func的实参
实参的不同表现形式:
核心都是数据值
# 实参的不同表现形式
def my_func(a, b):
print(a, b)
# 1.实参是具体的数值
my_func(1, 2) # 1 2
# 2.实参是一个变量
x = 10
y = 20
my_func(x, y) # 本质上还是 my_func(10, 20)
# 3.实参可以是一个函数的返回值
# 3.1
my_func(int('123'), int('345')) # 123 345
# 3.2
def my_func1():
return 111
def my_func2():
return 222
my_func(my_func1(), my_func2()) # 111 222
形参和实参的关系是:传参是以变量名=数据值的形式进行传递
在函数调用阶段,实参(值)和形参(变量名)临时绑定,函数调用完毕,二者断开(了解)
二、形参与实参的具体使用
2.1 位置参数
位置即顺序,位置参数指的是按照顺序定义的参数,有两种情况:
- 在函数定义阶段,括号中从左到右填写的变量名就是位置形参,凡是按照这种形式定义的形参都必须被传值
def index(a, b, c): # 定义位置形参:a, b, c,三者都必须被传值
pass
- 在函数调用阶段,括号中从左到右传入的数据值就是位置形参,凡是按照这种形式定义的实参会按照从左到右的顺序与形参一一对应
index(1, 2, 3) # 对应关系为:a=1, b=2, c=3
练习:
# 定义一个函数,传入两个数字参数,功能是:返回大的
a = 10
b = 20
if a > b:
return a
else:
return b
# 输出结果:
# 20
2.2 关键字实参
在调用函数时,实参可以是key = value的形式,成为关键字参数,凡是按照这种形式定义的实参,可以完全不按照从左到右的顺序定义,但仍能为指定的形参赋值
index(b=1, a=2, c=6)
练习:
def func(a, b):
print(a, b)
# func(1, 2) # 按照位置一一对应传值
# func(1) # ×,少一个不行
# func(1, 2, 3) # ×, 多一个不行
# func(a=1, b=2) # 关键字实参(指名道姓的传)
# func(b=2, a=1)
# func(b=1) # ×,少一个不行
# func(b=1, a=2, c=4) # ×,多一个不行
# func(1, b=2) # 混用
# func(b=2, 1) # ×,关键字实参一定要跟在位置参数的后面
# func(1, a=2) # ×, 1按照位置传参给了a,然后关键字传参又给a赋了值,多次赋值,错误
# func(1, a=2, b=3) # ×, 同一个形参在调用阶段不能多次赋值
"""
1. 在函数调用阶段,位置实参与位置形参一一对应传递
2. 实参个数与形参个数要一样,多一个不行,少一个也不行
3.同一个形参在调用阶段不能多次赋值
4.(重要)格式越简单,越往前放
"""
2.3 默认参数
在函数定义阶段,就可以给变量赋值了。
- 在调用阶段如果你给了数据值,就使用你给的
- 在调用阶段如果你不传数据值,那就使用默认的数据值
练习1:
# 定义一个函数,功能是注册(name, age, gender)
def register(name, age, gender='male'):
print("%s:%s:%s" % (name, age, gender))
register('kevin', 19)
register('kevin1', 19)
register('kevin2', 19, 'female')
"""
1. 函数在定义阶段,参数的传递已经固定死了
2. 根据变量名与变量值得绑定关系理解
"""
练习2:
# 参数的默认值如果给的是一个列表,那么,后续的数据都会指向同一个列表,(同一个内存空间)
def my_func(name, age, hobby=[]):
hobby.append(age)
print("%s:%s:%s" % (name, age, hobby))
my_func('kevin1', '20')
my_func('kevin2', '18')
my_func('kevin3', '39')
# 输出结果:
# kevin1:20:['20']
# kevin2:18:['20', '18']
# kevin3:39:['20', '18', '39']
"""注意事项:默认值是可变类型的时候,要注意多次调用函数的时候,数据值的变化"""
# 想要后面只有一个值
my_func('kevin1', '20', [])
my_func('kevin2', '18', [])
my_func('kevin3', '39', [])
# 输出结果:
# kevin1:20:['20']
# kevin2:18:['18']
# kevin3:39:['39']
练习3:
x = 100
def index(a, b, c=x):
print(a, b, c)
x = 200
index(1, 2)
# 输出结果
# 1 2 100
为什么c的值是100而不是200呢?
解释:第一步.把100赋值给x,第二步.函数在定义阶段,把100赋值给了c,第三步.把200赋值给了x,那100到x的赋值就断掉了,第四步.调用函数时,c的值仍然是100
补充:
# 加个f,就相当于格式化输出format
name = 'kevin'
age = 18
s = f'my name is {name}, my age is {age}'
print(s) # my name is kevin, my age is 18
2.4 可变长参数(*与**的用法)
2.4.1 可变长形参
- *的使用
# 1. 不管传入多少个位置参数,函数都可以正常运行
def func1(*a):
print(a)
func1() # ()
func1(1) # (1,)
func1(1, 2) # (1, 2)
def func2(b, *a):
print(b, a)
# func2() # ×, 函数至少需要一个参数给到b
func2(1) # 1 ()
func2(1, 2) # 1 (2,)
func2(1, 2, 3, 4) # 1 (2, 3, 4)
func2(1, 2, 3, 4, 5, 6, 7) # 1 (2, 3, 4, 5, 6, 7)
"""
*在形参中的使用:接收多余的位置参数,并组装成元素的形式返回
"""
- **的使用
# 2. 不管传入多少个关键字参数,函数都可以正常运行
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'}
"""
**在形参中得使用:接收多余的关键字参数,并把关键字参数组织成字典的形式返回
"""
3.混合使用
# 3. 不管传入多少个位置参数和关键字参数,函数都可以正常运行
def func5(n, *a, **k):
print(n, a, k)
# func5() # 函数至少需要一个参数给到n
func5(1, 2, 3) # 1 (2, 3) {}
func5(111, a=1, b=2, c=3) # 111 () {'a': 1, 'b': 2, 'c': 3}
func5(n=111, a=1, b=2, c=3) # 111 () {'a': 1, 'b': 2, 'c': 3}
func5(a=1, b=2, c=3, n=111) # 111 () {'a': 1, 'b': 2, 'c': 3}
func5(1, 2, 3, a=1, b=2, c=3) # (2, 3) {'a': 1, 'b': 2, 'c': 3}
- 四种形式都存在
def index(a, b, *c, name, **d):
print(a, b, c)
print(name, d)
index(1, 2, 3, 4, 5, name='kevin', age=20, gender='male')
# 输出结果:
# 1 2 (3, 4, 5)
# kevin {'age': 20, 'gender': 'male'}
"""
*和**后面的变量名可以随意的起名字,只是一个变量名而已
python中推荐使用
*args arguments
**kw args keyword arguments
def index(*args, **kwargs):
pass
"""
2.4.1 可变长实参(非常重要)
- *的使用
def index(a, b, *args):
print(a, b, args)
l = [11, 22, 33, 44, 55]
# index(l[0], l[1], l[2]) # 使用列表索引方式传值太麻烦
index(*l) # <==>index(11, 22, 33, 44, 55)
# 输出结果:11 22 (33, 44, 55)
t = (11, 22, 33, 44, 55)
index(*t) # <==>index(11, 22, 33, 44, 55)
# 输出结果:11 22 (33, 44, 55)
"""
*在实参中得使用:把容器类型的数据一一打散,然后传递给形参,字典是传键
"""
- **的使用
dict = {'username': 'kevin', 'age': '18', 'gender': 'male'}
# index(username='kevin', age='age', gender='male')
# """
# **在实参中得使用:把字典内的元素打散,然后以关键字的形式一一传入
# """
index(**dict) # <==> index(username='kevin', age='age', gender='male')
"""
**在实参中得使用:把字典内的元素打散,然后以关键字的形式一一传入
"""
2.5 命名关键字参数(了解)
单独一个*的使用
# 单独一个*,表示星号后面的参数统统按照关键字的形式传参
def register(name, age, *, sex='male', height):
print('Name:%s,Age:%s,Sex:%s,Height:%s' % (name, age, sex, height))
register('kevin', 20, sex='male', height='180')
# 输出结果:
# Name:kevin,Age:20,Sex:male,Height:180
# register('kevin',20, 'male','180') # ×, 不能以这种方式传参