Python中函数参数类型和参数绑定

Posted 北洛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python中函数参数类型和参数绑定相关的知识,希望对你有一定的参考价值。

参数类型

Python函数的参数类型一共有五种,分别是:

  • POSITIONAL_OR_KEYWORD(位置参数或关键字参数)
  • VAR_POSITIONAL(可变参数)
  • KEYWORD_ONLY(关键字参数)
  • VAR_KEYWORD(可变关键字参数)
  • POSITIONAL_ONLY(位置参数)

 

下面用举几个例子解释一下这5个参数类型的含义:

      

POSITIONAL_OR_KEYWORD如其名所见,既可以用位置传参,也可以用关键字传参,并且他没有任何*的声明

>>> def foo(name):
...     print(name)
...
>>> foo("hello")
hello
>>> foo(name="hello")
hello

  

VAR_POSITIONAL是可变参数,通过*来声明,它会把接收到的值存入一个元组

>>> def foo(*args):
...     print(args)
...
>>> foo(1, 2, 3, 4, 5)
(1, 2, 3, 4, 5)

  

KEYWORD_ONLY只能通过关键字传参,这种参数会在VAR_POSITIONAL参数类型的后面,而且不带**前缀,如同语义,只能通过指定关键字来传参,不可以用位置传参

>>> def foo(n1, *, n2):
...     print(n1, n2)
...
>>> foo("hello", n2="world")
hello world

  

VAR_KEYWORD是可变关键字参数,通过前缀**来声明,这种参数类型可以接收0个或多个参数,并存入一个字典

>>> def foo(**kwargs):
...     for key, value in kwargs.items():
...         print("%s=%s" % (key, value))
...
>>> foo(a=1, b=2, c=3)
a=1
b=2
c=3

  

POSITIONAL_ONLY是第五个参数类型,但是它已经不重要了,因为高版本的Python无法创建一个POSITIONAL_ONLY类型的参数,但是有些使用C语言实现且不接收关键字参数的函数(如divmod)支持

 

从下面的例子,我们可以看到,新定义的foo函数,每个参数都对应到上面的一个类型

>>> def foo(name, *args, middle=None, **kwargs):
...     print("name:", name)
...     print("args:", args)
...     print("middle:", middle)
...     print("kwargs:", kwargs)
...
>>> foo("hello", 1, 2, 3, middle="world", a=1, b=2, c=3)
name: hello
args: (1, 2, 3)
middle: world
kwargs: {‘a‘: 1, ‘b‘: 2, ‘c‘: 3}
>>> my_foo = {"name": "hello", "middle": "world", "a": "1", "b": "2", "c": "3"}
>>> foo(**my_foo)
name: hello
args: ()
middle: world
kwargs: {‘a‘: ‘1‘, ‘b‘: ‘2‘, ‘c‘: ‘3‘}
>>> from inspect import signature
>>> sig = signature(foo)
>>> for name, param in sig.parameters.items():
...     print(param.kind, ":", name, ‘=‘, param.default)
...
POSITIONAL_OR_KEYWORD : name = <class ‘inspect._empty‘>
VAR_POSITIONAL : args = <class ‘inspect._empty‘>
KEYWORD_ONLY : middle = None
VAR_KEYWORD : kwargs = <class ‘inspect._empty‘>

  

参数绑定

将函数的参数绑定到一个字典上

>>> def foo(name, *args, middle=None, **kwargs):
...     print("name:", name)
...     print("args:", args)
...     print("middle:", middle)
...     print("kwargs:", kwargs)
...
>>> my_foo = {"name": "hello", "middle": "world", "a": "1", "b": "2", "c": "3"}
>>> from inspect import signature
>>> sig = signature(foo)
>>> bound_args = sig.bind(**my_foo)
>>> for name, value in bound_args.arguments.items():
...     print(name, ‘=‘, value)
...
name = hello
middle = world
kwargs = {‘a‘: ‘1‘, ‘b‘: ‘2‘, ‘c‘: ‘3‘}
>>> del my_foo["name"]
>>> bound_args = sig.bind(**my_foo)
Traceback (most recent call last):
...
TypeError: missing a required argument: ‘name‘

  

在inspect模块的帮助下,展示了Python数据模型把实参绑定给函数调用的形参的机制,这与解释器使用的机制相同,当我们删除字典中的name,执行时会报错缺少name参数

以上是关于Python中函数参数类型和参数绑定的主要内容,如果未能解决你的问题,请参考以下文章

python 函数参数的类型

Python函数的参数类型

Swift6-函数

python_如何定义带参数的装饰器?

无法在成员函数中绑定右值引用参数

Vscode推荐一款适用于Python的快速函数注释插件