一 位置参数
- 调用函数时传入实际参数的数量和位置都必须和定义函数时保持一致。 ```bash def person(name,age): print(‘name:’,name,’age:’,age)
if name == ‘main‘: name_1 = ‘zxy’ age_1 = 15 person(name=name_1,age=age_1)
- 位置参数可传入的时候可以不写参数名
```bash
def person(name,age):
print('name:',name,'age:',age)
if __name__ == '__main__':
name_1 = 'zxy'
age_1 = 15
person(name_1,age_1)
对于位置参数传参的时候一般不写参数名(name=name_1,等号左边是变量(即函数的参数,名为name),右边是将name_1 = ‘zxy’的值赋值给左边的变量name,等号左边的是参数,右边是传入的参数的值)
一 可变参数
在传入的参数个数的不确定的时候,我们可以使用可变参数
- *args
- 可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。
- 调用的时候需要先组装一个tuple或者list
- 可变参数不需传入参数名(因为函数定义的参数个数、参数名未知)
```python
def calc(*args):
“””
函数传入可变参数
:return:计算传入数据的总和
“””
sum = 0
for i in args:
return sumsum +=i
if name == ‘main‘: print(calc(1,2,3))
- 如果已经有一个list或者tuple,要调用一个可变参数怎么办?Python允许你在list或tuple前面加一个*号,把list或tuple的元素变成可变参数传进去
```python
def calc(*args):
"""
函数传入可变参数
:return:计算传入数据的总和
"""
sum = 0
for i in args:
sum +=i
return sum
if __name__ == '__main__':
num_list = [1,2,3]
print(calc(*num_list))
# 结果
--> 6
- 以下是可变参数的案例: ```bash def person(name,age,*args): print(‘name:’,name,’age:’,age,’other:’,args)
if name == ‘main‘: name_1 = ‘zxy’ age_1 = 15 city_1 = ‘Beijign’ gender_1 = ‘男’ person(name_1,age_1,city_1,gender_1)
输出:
```bash
name: zxy age: 15 other: ('Beijign', '男')
可变参数与位置参数不一样,不能传入参数名,否则会报错:
def person(name,age,*args):
print('name:',name,'age:',age,'other:',args)
if __name__ == '__main__':
name_1 = 'zxy'
age_1 = 15
city_1 = 'Beijign'
gender_1 = '男'
person(name_1,age_1,city = city_1,gender = gender_1)
# 报错:
person(name_1,age_1,city = city_1,gender = gender_1)
TypeError: person() got an unexpected keyword argument 'city'
理解:
- city与gender都是可变参数,会被组装在一个tuple对象中,而这个tuple对象会会被赋值给变量args,此时局部变量args指向了一个tuple对象
- 函数调用时传入的参数,会按照从左到右的顺序依次在函数中使用,最左侧的参数先由位置参数name、age使用(匹配),剩下的所有未匹配的参数会被自动收集到1个新的tuple对象中,而局部变量args会指向这个新的tuple对象
-
二 关键字参数
关键字参数必须传入参数名,如果没有传入参数名,调用将报错
- 关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
- 关键字参数有什么用?它可以扩展函数的功能。比如,在person函数里,我们保证能接收到name和age这两个参数,但是,如果调用者愿意提供更多的参数,我们也能收到。试想你正在做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,利用关键字参数来定义这个函数就能满足注册的需求。
- 和可变参数类似,也可以先组装出一个dict,然后,把该dict转换为关键字参数传进去: ```python def person(name,age,**kwargs): print(‘name:’,name,’age:’,age,’other:’,kwargs)
if name == ‘main‘: name = ‘zxy’ age = 15 extra = {‘city’:’Beijing’,’gender’:’男’} person(name,age,**extra)
```python
# 输出
--> name: zxy age: 15 other: {'city': 'Beijing', 'gender': '男'}
- **extra表示把extra这个dict的所有key-value用关键字参数传入到函数的**kwargs参数,kw将获得一个dict,注意kw获得的dict是extra的一份拷贝,对kw的改动不会影响到函数外的extra。 ```python def person(name,age,**kwargs): print(‘name:’,name,’age:’,age,’other:’,kwargs)
if name == ‘main‘: name_1 = ‘zxy’ age_1 = 15 city_1 = ‘Beijign’ gender_1 = ‘男’ person(name_1,age_1,city = city_1,gender = gender_1)
- 传入的city、gender为关键字参数,python会在函数将关键字参数装进一个dict对象中,组装后dict对象会赋值给变量名kwargs,此时局部变量kwargs指向一个dict对象
```python
# 输出
--> name: zxy age: 15 other: {'city': 'Beijign', 'gender': '男'}
- 关键字参数必须传入参数名,如果没有传入参数名,调用将报错:() ```python def person(name,age,**kwargs): print(‘name:’,name,’age:’,age,’other:’,kwargs)
if name == ‘main‘: name_1 = ‘zxy’ age_1 = 15 city_1 = ‘Beijign’ gender_1 = ‘男’ person(name_1,age_1,city_1,gender_1)
报错:
person(name_1,age_1,city_1,gender_1)
TypeError: person() takes 2 positional arguments but 4 were given
<a name="tlbXN"></a>
# 三 命名关键字参数
- 关键字参数,函数的调用者可以传入任意不受限制的关键字参数。至于到底传入了哪些,就需要在函数内部通过kw检查。
- 命名关键字参数需要一个特殊分隔符 * ,*后面的参数被视为命名关键字参数。
- 命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错:
- 使用命名关键字参数时,要特别注意,如果没有可变参数,就必须加一个*作为特殊分隔符。如果缺少*,Python解释器将无法识别位置参数和命名关键字参数
- 如果要限制关键字参数的名字,就可以用命名关键字参数,例如,只接收city和gender作为关键字参数。这种方式定义的函数如下:
```python
def person(name,age,*,city,gender):
print('name:',name,'age:',age,'city:',city,'gender:',gender)
if __name__ == '__main__':
name_1 = 'zxy'
age_1 = 15
city_1 = 'Beijign'
gender_1 = '男'
person(name_1,age_1,city=city_1,gender=gender_1)
- 命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错
四 总结
- 数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
- *args是可变参数,args接收的是一个tuple
- **kw是关键字参数,kw接收的是一个dict