簡體   English   中英

Python mypy static 鍵入:僅接受 arguments 的字典(帶鍵 str)、列表(但不是自定義類)和嵌套字典和列表

[英]Python mypy static typing: Accept only arguments of Dict (with key str), Lists (but not of custom classes), and Nested Dicts and Lists

我想要一個 function 來接受 YAML 樣式的參數,它可以是列表或字典。 例如

foo({'a': 1})foo([{'a': 1}, {'b': 2, 'c': [1,2]}])foo({'a': {'b': 1}})

如果它是一個字典,鍵必須是一個字符串,值必須是一個Union[int, float, str] ,這些列表,另一個具有相同類型規則的字典,或者一個字典列表具有相同的規則。 如果它是一個列表,它可以是一個Union[int, float, str]列表,一個字典列表,或者一個與自身規則相同的列表列表。

不應允許自定義類,並且任何 dict 的鍵必須是字符串。

我可以簡單地做:

def foo(yaml_args : Union[List[Any], Dict[str, Any]):
    pass

但我想避免使用Any

到目前為止,我最好的嘗試是:

from typing import Dict, List, Union

ScalarPod = Union[int, float, str]
Pod = Union[ScalarPod, List[ScalarPod]]

NestedDict = Dict[str, Union[
    Pod,
    Dict[str, Union[
        Pod,
        Dict[str, Union[
            Pod,
            Dict[str, Pod]
        ]]
    ]]
]]

def foo(yaml_args : NestedDict):
    print(str(yaml_args))
    
foo({
        'number' : 1,
        'number_list' : [1, 2, 3],
        'dict_a' : 
        {
            'number_list_b' : [2,3,4],
            'number_b' : 3 
        },
        'dict_b' :
        {
            'nested_dict' :
            {
                'number' : 1,
                'number_b' : 2,
            }
        },
        'dict_c' :
        {
            'nested_dict' :
            {
                'nested_2_dict' : 
                {
                    'number' : 1
                }
            }
        },
        'dict_list' : [
            {
                'a' : 1
            },
            {
                'b' : 2
            }
        ]
    }
)

這與我似乎無法修復的字典列表不同。

它還有一個缺點,就是它的最大深度限制為 3 個嵌套字典,但這不是游戲殺手。 如果它具有無限的深度,我會更喜歡,但這不是必需的。

我怎么能做到這一點? 提前致謝!

Mypy 是一個 static 類型檢查器。 您的輸入變量可以是您剛剛在第一句話中指出的 2 種類型。 因此它沒有 static(不變)類型。

可能的解決方案:將 Input 變量分成兩個不同類型的變量,並添加一個默認值 None。 然后在您的 function 中檢查哪個變量不是無,然后您可以使用該變量。

我找到了一種方法可以更輕松地支持更深的嵌套字典,但仍然不是字典列表:

ScalarPod = Union[int, float, str]
Pod = Union[ScalarPod, List[ScalarPod]]
PodDict = Dict[str, Pod]

T = TypeVar("T")

NestedDict = Dict[str, Union[
    Pod,
    T
]]

NestedDict = NestedDict[NestedDict[NestedDict[NestedDict[NestedDict[NestedDict[PodDict]]]]]]

a : NestedDict = {
        'number' : 1,
        'number_list' : [1.1, 2, 3],
        'dict_a' : 
        {
            'number_list_b' : [2,3,4],
            'number_b' : 3 
        },
        'dict_b' :
        {
            'nested_dict' :
            {
                'number' : 1,
                'number_b' : 2,
            }
        },
        'dict_c' :
        {
            'nested_dict' :
            {
                'nested_2_dict' : 
                {
                    'number' : 1
                }
            }
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM