python 3.6.8
def xx(test=1, sim=0.2):
return test + sim
print(xx.__defaults__, xx.__kwdefaults__)
我得到以下输出:
Python 3.6.8 (default, Dec 29 2018, 10:04:55)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.1.1 -- An enhanced Interactive Python. Type '?' for help.
Out[1]: (1, 0.2) None
我希望
Out[1]: None {'test': 1, 'sim': 0.2}
但是如果我更改
def xx(*args, arg1, test=1, sim=0.2):
return test + sim
print(xx.__defaults__, xx.__kwdefaults__)
我得到了我想要的东西:
Python 3.6.8 (default, Dec 29 2018, 10:04:55)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.1.1 -- An enhanced Interactive Python. Type '?' for help.
Out[1]: None {'test': 1, 'sim': 0.2}
但是我设计的函数应该只接受关键字类型的参数,即不接受*args
。
我需要获取参数列表(参数名称)和关键字参数的默认值。
我想念什么?
答案 0 :(得分:3)
我的功能在设计上应该只接受关键字类型的参数,即不接受* args
使用*
明确地说出来,然后您将获得所需的输出:
def foo(*, test=1): pass
print(foo.__kwdefaults__)
# {'test': 1}
def foo(test=1)
不会不将test
设为仅关键字的参数。它只是给test
提供默认值,但是test
仍可以作为位置参数传递,即foo(2)
。
答案 1 :(得分:2)
__kwdefaults__
仅适用于唯一被关键字接受的参数; per the docs:
__defaults__
-位置或关键字参数的任何默认值的元组__kwdefaults__
-仅关键字参数的所有默认值的映射
因此,如果可以 按位置传递它们,则它们会出现在__defaults__
中。如果要将参数设为仅关键字而不接受位置参数,请添加一个空的*
参数(Python 3中新增; Python 2中不可用):
def xx(*, test=1, sim=0.2):
return test + sim
*
之后的所有参数只能通过关键字传递。
答案 2 :(得分:2)
看着data model docs,我们看到__kwdefaults__
是
包含仅关键字参数默认值的字典。
仅关键字参数在PEP3102中引入。简而言之,它们是argument list中*args
或普通*
之后的任何参数。
因此,尽管test
中的sim
和def xx(test=1, sim=0.2):
在实际的函数调用中可能由关键字指定,但实际上它们被命名为位置参数,而不是关键字-仅。
一种简单的解决方法是使用*
将其设置为仅关键字:
def xx(*, test=1, sim=0.2):
如果您需要获取命名参数的默认值,也可以使用inspect
模块:
from inspect import signature, Parameter
defaults = {p.name: p.default for p in signature(xx).parameters if p.default is not Parameter.empty}
想法来自here。
此解决方案的优点是它将在一个位置报告位置默认值和关键字默认值。这样,您不必将功能限制为仅接受关键字参数。