我如何记录函数自变量的字典键?

问题描述 投票:2回答:2

我试图弄清楚如何在不使用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'})

enter image description here

如预期,some函数的类型提示显示类型Some,但不显示其键。

我想完成的是两件事。

  • 在函数参数为字典时(最重要)提供键提示
  • 使用狮身人面像生成文档,以便密钥反映在文档中。

编辑

如所指出的那样,我可以在某种程度上用**kwargs完成此操作,但这不是故意的。设置**kwargs也不会给我键入提示。

python python-sphinx mypy python-typing
2个回答
0
投票

我使用以下代码在某种程度上缩小了可能的解决方案。它满足大多数要求:

  • mypy类型检查通过
  • 显示键
  • 文档还显示键和类型
  • 此解决方案的主要特征是,mypy认为该值是可选值,因为具有默认值,因此该解决方案还不够完善。

使用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

enter image description here

在屏幕截图中,我可以看到mypy在抱怨期望的None值,在弹出帮助中,我们还可以看到正在传递的字典中所需的键以及正在传递的类型。设置为它。

该解决方案感觉很hacky,并且希望对其进行任何更正使其更具有Python风格的更正。


0
投票

我认为在这种情况下,向您的编辑器提交功能请求/提交拉取请求实际上可能更好,以提高其类型提示的质量。同样,使用狮身人面像,您可以提交拉取请求,以确保文档正确链接到Some的定义或在函数签名本身中包含更详细的描述。

毕竟,您面临的问题是您的编辑器/狮身人面像的限制,而不是Python或类型提示,如果从源头上解决问题,可能会获得更好的长期结果。

如果您使用Some的“构造函数”而不是传递dict文字,则可能会得到更好的结果。至少对我来说,这样做可以在使用PyCharm时获得Some的完整键提示。不知道您的编辑器是否也会出现这种情况:

some(Some(keya='key', another_key='nonething'))

请注意,执行Some(...)实际上只会在运行时返回一个普通的旧常规字典,因此这不会导致行为上的任何差异。

也可能值得尝试:

x: Some = {
    "keya": "key",
    "another_key": "nonething",
}
some(x)

...查看您的编辑器是否可以通过该表格提供更好的提示。

© www.soinside.com 2019 - 2024. All rights reserved.