形参与实参

形参

在构建函数时,括号内声明的参数。形参本质就是一个变量名,用来接收外部传来的值

  1. def index_1(a,b): # a和b就是index函数的形参
  2. print(a, b)

实参

在调用函数时,括号内传入的值,值可以是常量、变量、表达式或三者的组合

  1. def index_2(a, b):
  2. print(a, b)
  3. index_2(1, 2) # 1和2就是index函数的实参

形参与实参过程 (演示与关系)

  1. def index_2(a, b): # a和b就是index函数的形参
  2. print(a, b)
  3. index_2(1, 2) # 1和2就是index函数的实参

理解关系

调用index_2将实参1临时绑定给形参a,实参2临时绑定给形参b,函数体代码运行期间。通过形参直接使用到实参,运行完毕之后解除绑定,形参a、b处于没有绑定值得状态,等待下一次函数调用传入实参再次进行绑定

位置参数

位置形参

在构建函数阶段括号内从左往右依次填写的变量名

  1. def index_1(a,b): # a和b就是位置形参
  2. print(a, b)

位置实参

在函数调用阶段括号内从左往右依次传入的真实数据

  1. def index_2(a, b):
  2. print(a, b)
  3. index_2(1, 2) # 1和2就是位置实参

注意

  1. 位置形参与位置实参在绑定关系的时候就是按照从左往右的顺序依次绑定
  2. 位置形参与位置实参的个数要一致 多一个不行少一个也不行

关键字参数

出现在实参中,指名道姓的给形参传值 不需要遵循位置

  1. def index_3(a, b):
  2. print(a, b)
  3. index_3(b=1, a=2) # 指名道姓的说形参a接收数据2,b接收数据1
  4. index_3(b=1, 2) # 报错,关键字参数必须放在位置参数的后面
  5. index_3(1, a = 2) # 报错,形参只能指向一个实参
  6. index_3(1, b=2) # 相当于位置参数

默认参数

在函数定义阶段就已经给一些形参赋值了 ,后续如果不传值则使用默认的,后续如果传值则使用传入的,默认参数的出现也打破了形参与实参之间个数一致的情况,默认参数必须定义在位置参数的后面

使用

  1. def register(name, age, gender='male'):
  2. print("""
  3. 学员姓名:%s
  4. 学员年龄:%s
  5. 学员性别:%s
  6. """ % (name, age, gender))
  7. register('kevin', 18) # 不写则默认用定义值
  8. # 学员姓名: kevin
  9. # 学员年龄: 18
  10. # 学员性别: male
  11. register('jerry', 22, 'female') # 写则用自己传入的值
  12. # 学员姓名: jerry
  13. # 学员年龄: 22
  14. # 学员性别: female

注意⚠️

1.默认参数必须在位置参数之后

2.默认参数的值仅在函数定义阶段被赋值一次

  1. a = 1
  2. def index(b=a):
  3. print(b)
  4. a = 5
  5. index()
  6. # 1

3.默认参数的值通常应设为不可变类型

  1. def index(a, b=[]):
  2. b.append(a)
  3. return b
  4. print(index(1))
  5. # [1]
  6. print(index(2))
  7. # [1, 2]
  8. print(index(3))
  9. # [1, 2, 3]

每次调用是在上一次的基础上向同一列表增加值

  1. def index(a, b=None):
  2. if b is None:
  3. b = []
  4. b.append(a)
  5. return b
  6. print(index(1))
  7. # [1]
  8. print(index(2))
  9. # [2]
  10. print(index(3))
  11. # [3]

可变长度位置参数

当在调用函数时,传入很多实参,可以在形参数前加*,可以将多余的位置参数组织成元组的形式,赋值给*号后面的变量名

使用

  1. def index(a, b, *c): # 如果形参为常规的参数(位置或默认),实参仍可以是*的形式
  2. print(a,b,c)
  3. index(1,2,3,4,5)
  4. # 1 2 (3, 4, 5)
  5. index(1,2)
  6. # 1,2 ()
  7. index(1) # 报错,还有b形参没有参数
  8. e = [1, 2, 3, 4, 5]
  9. index(1,2,e)
  10. # 1 2 ([1, 2, 3, 4, 5],)
  11. index(1,2,*e) # 等价于 index(1, 2,(1, 2, 3, 4, 5))
  12. # 可以把*号看成会将列表和元组的括号去除,暴露出里面一个个元素
  13. # 1 2 (1, 2, 3, 4, 5)
  14. index(*[1, 2, 3, 4, 5])
  15. # 1 2 (3, 4, 5)

求多个值的和

  1. def num(*add):
  2. count = 0
  3. for i in add:
  4. count += i
  5. return print(count)
  6. num(1, 2, 3, 4, 5, 6, 7, 8, )
  7. # 36

可变长度关键字参数

当在调用函数时,传入很多实参,可以在形参数前加**,可以将多余的位置参数组织成字典的形式,赋值给**号后面的变量名

使用

  1. def index(a, b, **c):
  2. print(a,b,c)
  3. index(1, 2, **{'c': '3', 'd': '4'})
  4. # 1 2 {'c': '3', 'd': '4'}
  5. index(1, 2, c=3, d=4) # 可以将字典打散成关键字参数一一传入
  6. # 1 2 {'c': 3, 'd': 4}
  7. index(1, 2)
  8. # 1 2 {}
  9. e = {'c': 3,'d': 4 }
  10. index(1, 2, **e)
  11. # 1 2 {'c': 3, 'd': 4}
  12. index(**{'a': 1, 'b': 2, 'c': 3, 'd': '4'})
  13. # 1 2 {'c': 3, 'd': '4'}

补充:以后在定义函数的时候 如果不确定这个函数将来需要多个实参 那么可以采用上述的方法

组合

***在形参中的使用 后面的变量名并不是关键,但是针对这两个特殊符号后面的变量名 有推荐的写法

使用

  1. def index(*args, **kwargs):
  2. pass
  3. # *和**不单单可以在形参中使用 还可以在实参中使用