Day 19:Python 函数五类参数

Python 五类参数

  • 默认参数
  • 位置参数(positional argument)
  • 关键字参数(keyword argument)
  • 可变位置参数
  • 可变关键字参数

默认参数很好理解,如果不传参给那个参数的话,就使用定义时候设置的默认值:

def f(a=0):
    print(f'a:{a}')
#两种调用方式
f()
f(1)

output:
0
1

 

  如果一个函数有一个参数a,根据调用函数f时的传参方式不同,a即可能是位置参数,也可能是关键字参数。

def f(a):
  print(f'a:{a}')

位置参数的调用

f(1)

a:1

关键字参数的调用

f(a=1)

a:1

  

  如果有一个函数以如下方式定义:

def f(a, *b, **c):
    print(f'a:{a},b:{b},c:{c}')

函数 f 的参数稍显复杂,但也是最常用的函数参数定义结构。

  • 出现带一个星号的参数 b,这是可变位置参数,被解析为元组
  • 两个星号的参数 c,这是可变关键字参数,被解析为字典
f(1,2,3,w=4,h=5)
f(1,2,w=4)

output:
a:1,b:(2, 3),c:{'w': 4, 'h': 5}
a:1,b:(2,),c:{'w': 4}

可变表示函数被赋值的变量个数是变化的。

查看参数

借助 Python 的 inspect 模块查看参数的类型: 

from inspect import signature
def f(a,*b):
    print(f'a:{a},b:{b}')

for name,val in signature(f).parameters.items():
    print(name,val.kind)

output:
a POSITIONAL_OR_KEYWORD
b VAR_POSITIONAL

参数 a 既可能是位置参数,也可能是关键字参数。参数 b 为可变位置参数。

from inspect import signature
def f(*,a,**b):
  print(f'a:{a},b:{b}')
for name,val in signature(f).parameters.items():
    print(name,val.kind)

output:
a KEYWORD_ONLY
b VAR_KEYWORD

a 只可能为 KEYWORD_ONLY 关键字参数。就是因为定义a之前定义了一个*号,划重点,*号后面的参数只可能是关键字参数,不可能是位置参数

传递规则

Python函数定义时有一定的约束规则。如果不了解这些规则,函数调用时,可能会出现各种各样的调用异常。

常见的异常有以下六类:

  • SyntaxError: positional argument follows keyword argument,位置参数位于关键字参数后面
  • TypeError: f() missing 1 required keyword-only argument: 'b',必须传递的关键字参数缺失
  • SyntaxError: keyword argument repeated,关键字参数重复
  • TypeError: f() missing 1 required positional argument: 'b',必须传递的位置参数缺失
  • TypeError: f() got an unexpected keyword argument 'a',没有这个关键字参数
  • TypeError: f() takes 0 positional arguments but 1 was given,不需要位置参数但却传递 1 个

为了避免这些错误,只要摸索正确的使用规则就好了。

规则 1:不带默认值的位置参数缺一不可
规则 2:关键字参数(通过键=值传参的)必须在位置参数右边
def f(a,b):
    pass

f(a=1,20)

output:
  File "<ipython-input-21-bdc62c937217>", line 4
    f(a=1,20)
         ^
SyntaxError: positional argument follows keyword argument
规则 3:对同一个形参不能重复传值
def f(a,**b):
    passf(1,width=20.,width=30.)

SyntaxError: keyword argument repeated
规则 4:默认参数的定义应该在位置形参右面,默认参数通常应该定义成不可变类型。
规则 5:可变位置参数不能传入关键字参数
def f(*a):
  print(a)
f(1)
f(1,2,3)
f(1,'ss',[1,2,3],4)
#可变位置参数不能传入关键字参数
f(a=1)

output:
(1,)
(1, 2, 3)
(1, 'ss', [1, 2, 3], 4)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-24-e485cc7c8886> in <module>()
      5 f(1,'ss',[1,2,3],4)
      6 #可变位置参数不能传入关键字参数
----> 7 f(a=1)

TypeError: f() got an unexpected keyword argument 'a'
规则 6:可变关键字参数不能传入位置参数
def f(**a):
  print(a)

f(a=1)
f(a=1,b=2,width=3,lst=['a',['ssd',2,'s']])
f(1)

output:
{'a': 1}
{'a': 1, 'b': 2, 'width': 3, 'lst': ['a', ['ssd', 2, 's']]}
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-27-11c232a4bc21> in <module>()
      4 f(a=1)
      5 f(a=1,b=2,width=3,lst=['a',['ssd',2,'s']])
----> 6 f(1)

TypeError: f() takes 0 positional arguments but 1 was given

 

posted @ 2021-07-07 15:23  PiaYie  阅读(199)  评论(0编辑  收藏  举报