lur*_*her 4 reflection inspect python-3.x
我的印象是,您可以使用该inspect.Signature
函数来检索和区分位置参数和关键字参数。然而,情况似乎并非如此:
def foo(a,b,c, t=3, q=5):
print(a,b,c,t,q)
[(u, u.kind) for u in i.signature(foo).parameters.values()]
[(<Parameter "a">, <_ParameterKind.POSITIONAL_OR_KEYWORD: 1>),
(<Parameter "b">, <_ParameterKind.POSITIONAL_OR_KEYWORD: 1>),
(<Parameter "c">, <_ParameterKind.POSITIONAL_OR_KEYWORD: 1>),
(<Parameter "t=3">, <_ParameterKind.POSITIONAL_OR_KEYWORD: 1>),
(<Parameter "q=5">, <_ParameterKind.POSITIONAL_OR_KEYWORD: 1>)]
Run Code Online (Sandbox Code Playgroud)
因此,事实上,该kind
属性似乎对于区分位置参数和关键字参数毫无用处
所以这里的问题是:
我如何区分参数a,b,c
和参数t,q
,以便如果我要调用 foo:
#build args from signature with args = [a,b,c]
#build kwargs from signature with kwargs = {'t': t,'q': q}
foo(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
除非您将函数参数显式定义为 isPOSITIONAL_ONLY
或KEYWORD_ONLY
使用以下语法,否则所有参数的默认行为均为POSITIONAL_OR_KEYWORD
。Python 3.8+ 和以前版本的 Python 的行为之间存在差异。
/
在 Python 3.8+ 中,可以分别使用和语法指定参数是仅位置参数还是仅关键字参数*
。举个例子:
def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):\n ----------- ---------- ----------\n | | |\n | Positional or |\n | keyword Keyword only\n Positional only\n
Run Code Online (Sandbox Code Playgroud)\n之前的一切都/
只是位置;之后的所有内容都*
只是关键字。请注意,顺序问题 \xe2\x80\x93/
必须位于 之前*
。另外,如果您没有显式指定POSITIONAL_ONLY
或KEYWORD_ONLY
使用此语法,则所有参数都默认POSITIONAL_OR_KEYWORD
为该kind
属性的值。
这是由于 Python 3.8 中所做的更改所致。语法的行为在PEP 570/
中指定(遵循PEP 457)。在代码中:
>>> import inspect\n\n# Positional or keyword (default behavior)\n>>> def meow (a, b, c = 0, d = 1):\n... return (a * b + c) * d\n\n>>> {p.name: p.kind for p in inspect.signature(meow).parameters.values()}\n{\'a\': <_ParameterKind.POSITIONAL_OR_KEYWORD: 1>, \n \'b\': <_ParameterKind.POSITIONAL_OR_KEYWORD: 1>, \n \'c\': <_ParameterKind.POSITIONAL_OR_KEYWORD: 1>, \n \'d\': <_ParameterKind.POSITIONAL_OR_KEYWORD: 1>}\n\n# Positional only, positional or keyword, keyword only\n>>> def meow (a, /, b, c = 0, *, d = 1):\n... return (a * b + c) * d\n\n>>> {p.name: p.kind for p in inspect.signature(meow).parameters.values()}\n{\'a\': <_ParameterKind.POSITIONAL_ONLY: 1>, \n \'b\': <_ParameterKind.POSITIONAL_OR_KEYWORD: 1>, \n \'c\': <_ParameterKind.POSITIONAL_OR_KEYWORD: 1>, \n \'d\': <_ParameterKind.KEYWORD_ONLY: 1>}\n
Run Code Online (Sandbox Code Playgroud)\n在 PEP 570 之前,该/
语法不存在,但该*
语法确实存在(引入时尚未能找到确切的 PEP);尝试/
3.7 中的 会引发语法错误:
# Python 3.7 - we get an error if use the `/` syntax\n>>> def meow (a, /, b, c = 0, *, d = 1):\n File "<stdin>", line 1\n def meow (a, /, b, c = 0, *, d = 1):\n\n# If we omit the `/` but keep the `*`, it works\n>>> def meow (a, b, c = 0, *, d = 1):\n... return (a * b + c) * d\n\n>>> {p.name: p.kind for p in inspect.signature(meow).parameters.values()}\n{\'a\': <_ParameterKind.POSITIONAL_OR_KEYWORD: 1>, \n \'b\': <_ParameterKind.POSITIONAL_OR_KEYWORD: 1>, \n \'c\': <_ParameterKind.POSITIONAL_OR_KEYWORD: 1>, \n \'d\': <_ParameterKind.KEYWORD_ONLY: 1>}\n
Run Code Online (Sandbox Code Playgroud)\n除了 PEP 之外,我还发现这个快速总结有助于理解行为。
\n 归档时间: |
|
查看次数: |
1131 次 |
最近记录: |