Я хочу, чтобы функция принимала аргумент стиля YAML, который может быть либо списком, либо dict. например,
foo({'a' : 1})
, или foo([{'a' : 1}, {'b' : 2, 'c' : [1,2]}])
, или foo({'a' : {'b' : 1}})
Если это dict, ключ должен быть строкой, а значение должно быть Union[int, float, str]
, их список, другой словарь с теми же правилами ввода, что и он сам, или список словарей с такими же правилами. Если это список, это может быть список Union[int, float, str]
, список dicts или список списков с теми же правилами, что и он сам.
Никакие настраиваемые классы не должны быть разрешены, и ключ для любого 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 вложенных диктовок, но это не не убийца игр. Я бы предпочел, чтобы у него была неограниченная глубина, но это не является обязательным требованием.
Как я могу этого добиться? Заранее спасибо!