[英]Is it possible to deconstruct a dictionary into typed keyword arguments?
假設我有一本字典:
from typing import Dict
T: Dict[str, int] = {
'a': 2,
'b': 3,
}
現在我想定義一個 function 關鍵字 arguments 取自上面的字典:
def func(**T):
print (locals())
目標是正確完成 function 的類型檢查:
func(2) # should work
func('2') # should work
func(a=2) # should work
func([2]) # should report a type issue
func(c=2) # should give TypeError
我試過了,但我無法讓它工作。 這可能嗎?
這不完全是你要找的東西,但你可以試試typeguard
庫,我想你可以做類似的事情
from typing import Dict
from typeguard import check_type
def something(**kwargs):
check_type("kwargs", kwargs, Dict[str, int])
if __name__ == "__main__":
something(**{"A": 1})
something(**{"A": "1"})
但我認為您無法使用**kwargs
語法對實際的 function 調用進行類型檢查,因為參數名稱直到運行時才定義,因此在運行時之前無法為每個關鍵字參數分配類型。 如果你提前知道允許的值類型,你可以做類似的事情
from typing import Dict
from typeguard import typeguard, check_type
@typeguard
def something(a: int, b: int):
check_type("kwargs", kwargs, Dict[str, int])
if __name__ == "__main__":
something(**{"A": 1})
something(**{"A": "1"})
或者你可以做
from typing import Dict
from typeguard import typeguard
@typeguard
def something(kwargs: Dict[str, int]):
# then do something with **kwargs
_inner(**kwargs)
def _inner(**kwargs):
pass
if __name__ == "__main__":
something(**{"A": 1})
something(**{"A": "1"})
最近有一項關於允許使用TypedDict
來注釋PEP 692中的**kwargs
的機制的提案。 然而,討論仍在進行中 AFAIK 並且有一些有效的 arguments 反對這一點。
其中一個論點是缺乏對此類功能的強烈動機。 換句話說,你為什么真的需要這個? 以你的情況為例。 如果你已經在某處定義了一個類型化字典,並且你知道 function 必須采用這樣一個字典作為它的參數,為什么不以這樣一個字典的形式定義一個常規的 function 參數:
from typing import TypedDict
class SpecialDict(TypedDict, total=False):
a: int
b: int
def func(d: SpecialDict) -> None:
print(d)
if __name__ == "__main__":
func({"a": 1})
func({"b": 1})
func({"c": 1})
導致mypy
使用以下內容抱怨最后一行:
error: Extra key "c" for TypedDict "SpecialDict"
無論如何,在 function 關鍵字參數中,關鍵字參數都被視為字典,因此與普通字典相比,我真的看不到用它們構建 function 的好處。 特別是因為**kwargs
表示您似乎並不真正想要的靈活性。
除此之外,您的要求還有許多問題。 如果你像這樣定義一個 function def f(**kwargs): ...
,它只需要關鍵字 arguments 而沒有位置 arguments。這意味着這些都不起作用,無論你如何注釋 function:
func(2)
func('2')
func([2])
此外,您希望某些類型注釋導致TypeError
,這永遠不會自行發生,因為類型注釋主要是為了 static 類型檢查器的利益。 Python 解釋器根本不關心它們。
如果您確實希望它關心,則必須自己在運行時實現檢查類型的邏輯。
我建議堅持 Python 的禪宗並且更明確。 如果您真的希望您的 function 只接受特定關鍵字 arguments,請相應地定義它:
def func(*, a: int, b: int) -> None:
...
如果需要,您仍然可以通過使用正確的鍵解壓字典來調用它:
d = {"a": 1, "b": 2}
func(**d)
希望這可以幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.