2017-09-11 38 views
8

關鍵詞have to是字符串接受整數作爲** kwargs的鍵

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

但一些黑魔法,命名空間能夠繞過

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

爲什麼?和如何您能否實現一個可以在kwargs映射中接收整數的Python函數?

+1

更重要的問題:你爲什麼需要? –

+2

因此,簡而言之:您可以定義一個接受關鍵字參數的C擴展類型,這些類型不受限制。但是你不能定義一個相同的Python函數。 –

+2

不知道是否有任何其他Python分佈展現出相同的行爲... –

回答

6

您能否實現一個可以在kwargs映射中接收整數的Python函數?

不,你不能。 Python評估循環處理調用Python代碼中定義的函數與調用C代碼中定義的可調用對象的方式不同。處理關鍵字參數擴展的Python評估循環代碼堅定地關閉了非字符串關鍵字參數的大門。

但是SimpleNamespace不是Python定義的可調用函數,它被定義爲entirely in C code。它直接接受關鍵字參數,而不進行任何驗證,這就是爲什麼您可以傳遞包含非字符串關鍵字參數的字典。

這可能是一個bug;你應該使用C-API argument parsing functions,它們都會防範非字符串關鍵字參數。但SimpleNamespace僅被設計爲持有sys.implementation data*的對象,並且並非真正用於其他用途。

可能還有其他這樣的異常,但它們全都是C定義的可調用對象,而不是Python函數。


*time.get_clock_info() method也運行SimpleNamespace類的一個實例;這是該類型目前唯一使用的其他地方。