关键字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函数吗?
答案 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 8419(commit fb88636199c12f63d6c8c89f311cdafc91f30d2f)中的(我也相信Python 2.7.4,但不要在此引用我)检查调用kwarg是否为字符串(如果不是,则引发值错误)。它还向C-api中添加了PyArg_ValidateKeywordArguments
,只需执行上述检查即可。
2017年,issue 29951在PR 916(commit 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修复的。