我试图弄清楚如何在不使用Dict[str, str]
的情况下为传递给函数的字典参数提供类型提示,因为这不提供键的含义。
到目前为止,我已经尝试了两种方法,一种方法是使用typing_extensions
,以便可以与3.6兼容,也可以与pydantic
兼容,但是我无法显示出匹配的结果。
考虑此示例代码:
from typing_extensions import TypedDict
from pydantic import BaseModel
class Some(TypedDict):
"""keya is some key"""
keya: str
"""another_key is another key"""
another_key: str
def some(a: Some) -> None:
print(a.get('keya'))
return None
some({'keya': 'key', 'another_key': 'nonething'})
如预期,some
函数的类型提示显示类型Some
,但不显示其键。
我想完成的是两件事。
如所指出的那样,我可以在某种程度上用**kwargs
完成此操作,但这不是故意的。设置**kwargs
也不会给我键入提示。
我使用以下代码在某种程度上缩小了可能的解决方案。它满足大多数要求:
使用validate_items
函数,我可以验证值是否在那里。请查看代码段上的注释并提供建议。
from typing_extensions import TypedDict
from typing import Union
class Some(TypedDict):
keya: str
another_key: str
def validate_items(v: dict) -> None:
for key, value in v.items():
assert isinstance(value,str), '{} is required'.format(key)
# Would love to pull the type of a key from the Some class here or
# would love to put the validation in the Some class itself
def some(a: Some={'keya': '', 'another_key': ''}) -> None:
"""[summary]
Args:
a (Some, optional): [description]. Defaults to {'keya': '', 'another_key': ''}.
Returns:
[type]: [description]
"""
validate_items(dict(a))
print(a.get('keya'))
return None
在屏幕截图中,我可以看到mypy在抱怨期望的None
值,在弹出帮助中,我们还可以看到正在传递的字典中所需的键以及正在传递的类型。设置为它。
该解决方案感觉很hacky,并且希望对其进行任何更正使其更具有Python风格的更正。
我认为在这种情况下,向您的编辑器提交功能请求/提交拉取请求实际上可能更好,以提高其类型提示的质量。同样,使用狮身人面像,您可以提交拉取请求,以确保文档正确链接到Some的定义或在函数签名本身中包含更详细的描述。
毕竟,您面临的问题是您的编辑器/狮身人面像的限制,而不是Python或类型提示,如果从源头上解决问题,可能会获得更好的长期结果。
如果您使用Some
的“构造函数”而不是传递dict文字,则可能会得到更好的结果。至少对我来说,这样做可以在使用PyCharm时获得Some
的完整键提示。不知道您的编辑器是否也会出现这种情况:
some(Some(keya='key', another_key='nonething'))
请注意,执行Some(...)
实际上只会在运行时返回一个普通的旧常规字典,因此这不会导致行为上的任何差异。
也可能值得尝试:
x: Some = {
"keya": "key",
"another_key": "nonething",
}
some(x)
...查看您的编辑器是否可以通过该表格提供更好的提示。