[toc] 本片文章主要整合15. 函数和装饰器和python的可变参数和关键字参数(*args **kw)两篇文章,并做对比总结,以及添加综合案例。主要目标是熟悉 python 中函数传参种类和方法,并掌握不同传参的优缺点和联合传参的注意事项。 本文难免有不足之处,若对该主题感兴趣,如下的几个参考文献可能帮助到你

  1. python 3.10.4 函数定义详解部分
  2. Python 的函数是怎么传递参数的?

概要

五种函数参数类型对比表

种类 函数定义 参数传递 功能 参考
POSITIONAL_ONLY 位置参数 ord(c, /) 一些内置函数,只支持位置传入 1.1 POSITIONAL_ONLY 位置参数
POSITIONAL_OR_KEYWORD 位置或关键字参数 def foo(n): 自定义函数支持位置和关键字传入,这种类型最常见 基础传入方式,最常用
VAR_POSITIONAL 可变长参数 def variable_args(name="default", *args): 1. 传入列表 list<br />2. 传入元组 tuple<br /> 3. 传入逐个传入元素 降低变长数组和元组传入的复杂度 2.1 VAR_POSITIONAL 可变长参数 参数传递
KEYWORD_ONLY 关键字参数 def person(name, age, *, city, job): 1. city 和 job 通过关键字传入 限制输入的关键字参数 2.3命名关键字参数
VAR_KEYWORD 可变关键字参数 def person(name, age, **kw) 1. 关键字传入<br />2. 传入字典 dict 任意不受限,但是函数内部要增加检查 2.3VAR_KEYWORD 可变关键字参数 参数传递

接受任意多个参数的函数定义方法

定义一个可以处理任意类型任意参数数目的函数。

def test_args(*args, **kwargs):
    print(args)
    print(kwargs)

test_args(1, 2, {"key0": "val0"}, name="name", age=18)

>>>
(1, 2, {'key0': 'val0'})
{'name': 'name', 'age': 18}

test_args() 是一个可以接受任意多个参数的函数。由于参数处理是有优先级的,kwargs 和 args 顺序不可颠倒。

混合定义时注意事项

  1. 参数定义的顺序必须是:必选参数、默认参数、可变参数/命名关键字参数和关键字参数。
def f1(a, b, c=0, *args, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)

def f2(a, b, c=0, *, d, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)

>>> f1(1, 2)
a = 1 b = 2 c = 0 args = () kw = {}
>>> f1(1, 2, c=3)
a = 1 b = 2 c = 3 args = () kw = {}
>>> f1(1, 2, 3, 'a', 'b')
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
>>> f1(1, 2, 3, 'a', 'b', x=99)
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}
>>> f2(1, 2, d=99, ext=None)
a = 1 b = 2 c = 0 d = 99 kw = {'ext': None}

>>> args = (1, 2, 3, 4)
>>> kw = {'d': 99, 'x': '#'}
>>> f1(*args, **kw)
a = 1 b = 2 c = 3 args = () kw = {'d': 99, 'x': '#'}
>>> args = (1, 2, 3)
>>> kw = {'d': 88, 'x': '#'}
>>> f2(*args, **kw)
a = 1 b = 2 c = 3 d = 88 kw = {'x': '#'}

1 函数参数类型

Python 中的函数参数类型一共有五种,参考 inspect 模块 ,分别是:

  1. POSITIONAL_ONLY 位置参数,内置函数或模块使用,用户无法自定义一个只支持位置参数的函数。
  2. POSITIONAL_OR_KEYWORD 位置或关键字参数,参数同时支持位置或者关键字传递给函数。
  3. VAR_POSITIONAL 可变长参数,任意多个位置参数通过元组传递给函数。