Python函数参数类型与注解详解:定位、可变、默认及关键字参数

远山来客
远山来客
发布时间:2026-10-14 | 1人浏览过
原创

本文深入解析Python函数的四种核心参数类型:定位参数、*args可变参数、默认值参数及**kwargs关键字参数,并重点讲解Python3新增的仅限关键字参数定义规则。同时介绍如何利用__defaults__、__kwdefaults__及inspect库进行函数内省,以及使用类型注解提升代码可读性与IDE支持。

四种参数

Python函数func定义如下:


def func(first, *args, second="Hello World", **kwargs):
    print(first)
    print(args)
    print(second)
    print(kwargs)


func("dongfanger", "san", py="good")

运行后会输出:


dongfanger
('san',)
Hello World
{'py': 'good'}

它包含四种不同的参数类型:

  • first是定位参数(positional parameter),调用时不可省略。
  • *args是可变位置参数(arguments),接收到的额外位置参数会被存入元组。
  • second是默认值参数(default argument values),调用时可以省略,使用预设值。
  • **kwargs是关键字参数(keyword arguments),接收到的额外关键字参数会被存入字典。

func函数的调用方式包含以下几种情况:

①仅传入单个定位参数。


func("dongfanger")  

dongfanger
()
Hello World
{}

②第一个参数后的任意数量位置参数会被*args捕获,并打包为一个元组。


func("dongfanger", "a", "b", "c")

dongfanger
('a', 'b', 'c')
Hello World
{}

③未明确指定名称的关键字参数会被**kwargs捕获,并打包为一个字典。


func("dongfanger", j="1", k="2")

dongfanger
()
Hello World
{'j': '1', 'k': '2'}

④second参数只能以关键字参数的形式传入。


func("dongfanger", second="cool")

dongfanger
()
cool
{}

⑤定位参数也可以显式地作为关键字参数传入。


func(first="san")

san
()
Hello World
{}

⑥若字典前加上**,其所有键值对将作为单个参数传入,同名键会绑定到对应的具名参数上,剩余未匹配的键值对则被**kwargs捕获。


my_dict = {"first": "dongfanger", "location": "cd", "second": "cool", "age": "secret"}
func(**my_dict)

dongfanger
()
cool
{'location': 'cd', 'age': 'secret'}

除了上述四种参数,Python3还引入了一种仅限关键字参数(keyword-only argument)。

仅限关键字参数

仅限关键字参数是Python3的新特性。在func函数中,second参数即为仅限关键字参数,“仅限”意味着它只能通过关键字形式指定,绝不会捕获未命名的定位参数。

若调整参数位置定义another_func函数:


def another_func(first, another_second="Hello World", *args,  **kwargs):
    print(first)
    print(another_second)
    print(args)
    print(kwargs)


another_func("dongfanger", "a", "b", "c")

输出结果将变为:


dongfanger
a  # 注意这里
('b', 'c')
{}

此时another_second不再是仅限关键字参数,而退化为普通的默认值参数,因为它成功捕获到了定位参数。

由此可见,定义仅限关键字参数必须将其放置在*args之后,如func函数所示;反例即another_func函数。

另一种定义仅限关键字参数的方法是在签名中显式放置一个*:


>>> def f(a, *, b):  # b是仅限关键字参数
...    return a, b
...
>>> f(1, b=2)  # 只能传关键字参数
(1, 2)
>>> f(1, 2)  # 不能传定位参数
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: f() takes 1 positional argument but 2 were given
>>> f(1, 2, 3)  # 不能传定位参数
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: f() takes 1 positional argument but 3 were given

仅限关键字参数不一定需要默认值,例如参数b,若未提供默认值,则强制要求调用时必须传入实参。

内省中的函数参数

函数内省指的是当获取到一个“函数对象”时,可以进一步查询其名称、参数定义等元信息。这些信息可通过函数对象的属性(即双下划线开头的魔法方法)获取。

对于func函数:


def func(first, *args, second="Hello World", **kwargs):
    print(first)
    print(second)
    print(args)
    print(kwargs)

以及another_func函数:


def another_func(first, another_second="Hello World", *args,  **kwargs):
    print(first)
    print(another_second)
    print(args)
    print(kwargs)

【__defaults__属性】

该属性为元组,保存着定位参数和默认值参数的默认值。


print(func.__defaults__)  # None

print(another_func.__defaults__)  # ('Hello World',)

【__kwdefaults__属性】

该属性为字典,保存仅限关键字参数的默认值。


print(func.__kwdefaults__)  # {'second': 'Hello World'}

print(another_func.__kwdefaults__)  # None

【__code__属性】

该属性引用code对象,code对象自身包含多个属性,其中包括参数名称列表。


print(func.__code__.co_varnames)  # ('first', 'second', 'args', 'kwargs')

print(another_func.__code__.co_varnames)  # ('first', 'another_second', 'args', 'kwargs')

此外,还可以使用inspect库的signature方法来查看内省中的函数参数:


from inspect import signature

print(signature(func))  
# (first, *args, second='Hello World', **kwargs)

框架和IDE等开发工具可以利用这些信息进行代码验证和智能提示。

函数注解

如果熟悉力扣算法题,对函数注解应不陌生。例如:


def clip(text:str, max_len:'int > 0'=80) -> str:
    pass

参数名后的表达式为注解表达式,用于标注参数类型或约束条件。若参数存在默认值,注解需放置在参数名与=号之间。

可在函数定义末尾的)和:之间添加->及注解表达式,以对返回值类型进行注解。

注解表达式可以是任意类型,最常用的是类(如str或int)或字符串(如'int > 0')。

函数注解仅作为元数据存储,Python对注解的唯一处理是将其存入函数的__annotations__属性中:


print(clip.__annotations__)
#{'text': <class 'str'>, 'max_len': 'int > 0', 'return': <class 'str'>}

Python解释器不会检查、强制或验证注解,不做任何运行时操作!注解仅作为元数据供框架和IDE等工具使用。

以上就是Python函数参数和注解的使用的详细内容,更多关于Python函数参数和注解的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表