Python函数的5类参数使用详解

1 各种参数使用之坑

Python强大多变,原因之一在于函数参数类型的多样化。方便的同时,也为使用者带来更多的约束规则。如果不了解这些规则,调用函数时,可能会出现如下一些语法异常:

(1) SyntaxError: positional argument follows keyword argument

(2) TypeError: f() missing 1 required keyword-only argument: 'b'

(3) SyntaxError: keyword argument repeated

(4) TypeError: f() missing 1 required positional argument: 'b'

(5) TypeError: f() got an unexpected keyword argument 'a'

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

2 总结主要的参数使用规则

位置参数

位置参数的定义:函数调用时根据函数定义的参数位(形参)置来传递参数,是最常见的参数类型。

def f(a):
  return a

f(1) # 位置参数

位置参数不能缺少:

def f(a,b):
  pass

f(1) # TypeError: f() missing 1 required positional argument: 'b'

规则1:位置参数必须一一对应,缺一不可

关键字参数

在函数调用时,通过‘键--值’方式为函数形参传值,不用按照位置为函数形参传值。

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

这么调用,a就是关键字参数:

f(a=1)

但是下面调用就不OK:

f(a=1,20.) # SyntaxError: positional argument follows keyword argument

规则2:关键字参数必须在位置参数右边

下面调用也不OK:

f(1,width=20.,width=30.) #SyntaxError: keyword argument repeated

规则3:对同一个形参不能重复传值

默认参数

在定义函数时,可以为形参提供默认值。对于有默认值的形参,调用函数时如果为该参数传值,则使用传入的值,否则使用默认值。如下b是默认参数:

def f(a,b=1):
  print(f'a:{a}, b:{b}')

规则4:无论是函数的定义还是调用,默认参数的定义应该在位置形参右面

只在定义时赋值一次;默认参数通常应该定义成不可变类型

可变位置参数

如下定义的参数a为可变位置参数:

def f(*a):
  print(a)

调用方法:

f(1) #打印结果为元组:(1,)
f(1,2,3) #打印结果:(1, 2, 3)

但是,不能这么调用:

f(a=1) # TypeError: f() got an unexpected keyword argument 'a'

可变关键字参数

如下a是可变关键字参数:

def f(**a):
  print(a)

调用方法:

f(a=1) #打印结果为字典:{'a': 1}
f(a=1,b=2,width=3) #打印结果:{'a': 1, 'b': 2, 'width': 3}

但是,不能这么调用:

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

3 五类参数使用例子

今天举例说明python5类参数:位置参数,关键字参数,默认参数,可变位置或关键字参数的使用。

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

默认参数c不能位于可变关键字参数d后.

调用f:

In [10]: f(1,2,5,width=10,height=20)
a:1,b:(2, 5),c:10,d:{'width': 10, 'height': 20}

可变位置参数b实参后被解析为元组(2,5);而c取得默认值10; d被解析为字典.

再次调用f:

In [11]: f(a=1,c=12)
a:1,b:(),c:12,d:{}

a=1传入时a就是关键字参数,b,d都未传值,c被传入12,而非默认值。

注意观察参数a, 既可以f(1),也可以f(a=1) 其可读性比第一种更好,建议使用f(a=1)。如果要强制使用f(a=1),需要在前面添加一个星号:

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

此时f(1)调用,将会报错:TypeError: f() takes 0 positional arguments but 1 was given

只能f(a=1)才能OK.

说明前面的*发挥作用,它变为只能传入关键字参数,那么如何查看这个参数的类型呢?借助python的inspect模块:

In [22]: for name,val in signature(f).parameters.items():
    ...:     print(name,val.kind)
    ...:
a KEYWORD_ONLY
b VAR_KEYWORD

可看到参数a的类型为KEYWORD_ONLY,也就是仅仅为关键字参数。

但是,如果f定义为:

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

查看参数类型:

In [24]: for name,val in signature(f).parameters.items():
    ...:     print(name,val.kind)
    ...:
a POSITIONAL_OR_KEYWORD
b VAR_POSITIONAL

可以看到参数a既可以是位置参数也可是关键字参数。

了解更多例子,点击阅读原文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值