接受整数作为 **kwargs 的键
Accepting integers as keys of **kwargs
关键字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 函数吗?
Could you implement a Python function that can receive integers in the kwargs mapping?
不,你不能。 Python 评估循环处理调用 Python 代码中定义的函数的方式与调用 C 代码中定义的可调用对象的方式不同。处理关键字参数扩展的 Python 评估循环代码已经牢牢关闭了非字符串关键字参数的大门。
但是 SimpleNamespace
不是 Python 定义的可调用函数,它是 entirely in C code 定义的。它直接接受关键字参数,无需任何验证,这就是为什么您可以传入带有非字符串关键字参数的字典。
这可能是一个错误;你应该使用 C-API argument parsing functions, which all do guard against non-string keyword arguments. SimpleNamespace
was initially designed just as a container for the sys.implementation
data*,并不是真正为其他用途而设计的。
可能还有其他此类异常,但它们都是 C 定义的可调用对象,而不是 Python 函数。
* time.get_clock_info()
method 还运行 SimpleNamespace
class 的实例;这是当前唯一使用该类型的其他地方。
不,kwargs 不能是整数。然而,这个答案被设计为(非常)简短的历史课而不是技术答案(为此,请参阅@MartijnPierter 的答案)。
支票最初是在 2010 年 issue 8419 (commit fb88636199c12f63d6c8c89f311cdafc91f30d2f) 中为 Python 3.2 添加的(我相信 Python 2.7.4 也是如此,但不要引用我的话),并简单地检查 call kwargs 是否为字符串(如果不是则引发值错误)。它还将PyArg_ValidateKeywordArguments
添加到C-api,这只是执行了上述检查。
2017 年,issue 29951 changed the error text for Python 3.7 from "keyword arguments must be strings" to "keywords must be strings" in PR 916 (commit 64c8f705c0121a4b45ca2c3bc7b47b282e9efcd8)。错误仍然是 ValueError
,它 没有 以任何方式改变行为,只是对错误描述符的一个小改动。
SimpleNamespace 现在拒绝整数关键字键。正如 Martijn 推测的那样,the original behavior was a bug. It seems that it was fixed by bpo-31655: Validate keyword names in SimpleNamespace constructor in v3.9.0b2, and then backported to 3.6.
关键字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 函数吗?
Could you implement a Python function that can receive integers in the kwargs mapping?
不,你不能。 Python 评估循环处理调用 Python 代码中定义的函数的方式与调用 C 代码中定义的可调用对象的方式不同。处理关键字参数扩展的 Python 评估循环代码已经牢牢关闭了非字符串关键字参数的大门。
但是 SimpleNamespace
不是 Python 定义的可调用函数,它是 entirely in C code 定义的。它直接接受关键字参数,无需任何验证,这就是为什么您可以传入带有非字符串关键字参数的字典。
这可能是一个错误;你应该使用 C-API argument parsing functions, which all do guard against non-string keyword arguments. SimpleNamespace
was initially designed just as a container for the sys.implementation
data*,并不是真正为其他用途而设计的。
可能还有其他此类异常,但它们都是 C 定义的可调用对象,而不是 Python 函数。
* time.get_clock_info()
method 还运行 SimpleNamespace
class 的实例;这是当前唯一使用该类型的其他地方。
不,kwargs 不能是整数。然而,这个答案被设计为(非常)简短的历史课而不是技术答案(为此,请参阅@MartijnPierter 的答案)。
支票最初是在 2010 年 issue 8419 (commit fb88636199c12f63d6c8c89f311cdafc91f30d2f) 中为 Python 3.2 添加的(我相信 Python 2.7.4 也是如此,但不要引用我的话),并简单地检查 call kwargs 是否为字符串(如果不是则引发值错误)。它还将PyArg_ValidateKeywordArguments
添加到C-api,这只是执行了上述检查。
2017 年,issue 29951 changed the error text for Python 3.7 from "keyword arguments must be strings" to "keywords must be strings" in PR 916 (commit 64c8f705c0121a4b45ca2c3bc7b47b282e9efcd8)。错误仍然是 ValueError
,它 没有 以任何方式改变行为,只是对错误描述符的一个小改动。
SimpleNamespace 现在拒绝整数关键字键。正如 Martijn 推测的那样,the original behavior was a bug. It seems that it was fixed by bpo-31655: Validate keyword names in SimpleNamespace constructor in v3.9.0b2, and then backported to 3.6.