接受整数作为** kwargs

时间:2017-09-11 21:42:51

标签: python keyword-argument

关键字have to是字符串

>>> def foo(**kwargs):
...     pass
... 
>>> foo(**{0:0})
TypeError: foo() keywords must be strings

但是通过一些黑魔法,命名空间能够绕过那个

>>> from types import SimpleNamespace
>>> SimpleNamespace(**{0:0})
namespace()

为什么呢? 如何你能实现一个可以在kwargs映射中接收整数的Python函数吗?

3 个答案:

答案 0 :(得分:6)

  

你能实现一个可以在kwargs映射中接收整数的Python函数吗?

不,你不能。 Python评估循环处理Python代码中定义的调用函数与调用C代码中定义的可调用对象不同。处理关键字参数扩展的Python评估循环代码牢牢地关闭了非字符串关键字参数。

但是SimpleNamespace不是Python定义的可调用的,它被定义为entirely in C code。它直接接受关键字参数,没有任何验证,这就是为什么你可以传入一个带有非字符串关键字参数的字典。

这可能是一个错误;你应该使用C-API argument parsing functions,它们都会防止非字符串关键字参数。但SimpleNamespace仅设计为持有sys.implementation data * 的对象,并且并非真正用于其他用途。

可能还有其他类似的异常,但它们都是C定义的callables,而不是Python函数。

* time.get_clock_info() method也运行SimpleNamespace类的实例;它是目前使用该类型的唯一其他地方。

答案 1 :(得分:1)

否,kwarg不能为整数。但是,此答案被设计为(非常)简短的历史课程,而不是技术性的答案(为此,请参阅@MartijnPierter的答案)。

该支票最初是在2010年添加到Python 3.2的issue 8419commit fb88636199c12f63d6c8c89f311cdafc91f30d2f)中的(我也相信Python 2.7.4,但不要在此引用我)检查调用kwarg是否为字符串(如果不是,则引发值错误)。它还向C-api中添加了PyArg_ValidateKeywordArguments,只需执行上述检查即可。

2017年,issue 29951PR 916commit 64c8f705c0121a4b45ca2c3bc7b47b282e9efcd8)中将Python 3.7的错误文本从“关键字参数必须是字符串”更改为“关键字必须是字符串”。错误仍然是ValueError,它没有以任何方式改变行为,只是对错误描述符的一小部分改动。

答案 2 :(得分:1)

SimpleNamespace现在拒绝整数关键字键。正如Martijn所言,the original behavior was a bug。看来它是由v3.9.0b2中的bpo-31655: Validate keyword names in SimpleNamespace constructor,然后是backported to 3.6修复的。