简体   繁体   English

我如何记录函数参数的字典键?

[英]How can i document dictionary keys for a functions argument?

I am trying to figure out how can I provide type hints for a dictionary argument being passed to a function without using Dict[str, str] as that doesnt provide what the keys will be.我试图弄清楚如何在不使用Dict[str, str]的情况下为传递给 function 的字典参数提供类型提示,因为它不提供键的含义。

I have tried two approaches so far, one with using typing_extensions so that I can have compatibility with 3.6, and also with pydantic , but I cant get the hits to show.到目前为止,我已经尝试了两种方法,一种是使用typing_extensions以便我可以与 3.6 兼容,也可以与pydantic ,但我无法显示命中。

Consider this example code:考虑这个示例代码:

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'})

在此处输入图像描述

As expected, the type hints for the some function shows the type Some , but not its keys.正如预期的那样, some function 的类型提示显示类型Some ,但不显示其键。

What I am trying to accomplish is 2 things.我想要完成的是两件事。

  • Provide key hints when the function argument is a dict (most important)当 function 参数是字典时提供关键提示(最重要)
  • Generate documentation with sphinx so that the keys reflect in the documentation.使用 sphinx 生成文档,以便键反映在文档中。

Edit编辑

As on of the comments pointed out, I can accomplish this with **kwargs to some extent, but that is not the intention.正如评论指出的那样,我可以在某种程度上使用**kwargs来完成此操作,但这不是本意。 Setting **kwargs does not give me type hints either.设置**kwargs也不会给我类型提示。

I think in this case, it might actually be better to file a feature request/submit a pull request to your editor improving the quality of its type hinting.我认为在这种情况下,向编辑器提交功能请求/提交拉取请求实际上可能会更好,以提高其类型提示的质量。 Similarly, with sphinx, you could submit a pull request that ensures that the docs either properly link to the definition of Some or include a more detailed description within the function signature itself.同样,使用 sphinx,您可以提交一个拉取请求,以确保文档正确链接到 Some 的定义,或者在 function 签名本身中包含更详细的描述。

After all, the problem you're facing is a limitation of your editor/sphinx, not with Python or type hints, and you might get better long-term results if you tackle the problem at the source.毕竟,您面临的问题是您的编辑器/狮身人面像的限制,而不是 Python 或类型提示,如果您从源头解决问题,您可能会获得更好的长期结果。

You may also get better results if you use the "constructor" of Some instead of passing in a dict literal.如果您使用Some的“构造函数”而不是传入 dict 文字,您也可能会获得更好的结果。 At least for me, doing this gets me full key hints for Some when using PyCharm.至少对我来说,这样做可以让我在使用 PyCharm 时获得Some完整的关键提示。 Not sure if that'll also be the case for your editor:不确定您的编辑器是否也会出现这种情况:

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

Note that doing Some(...) will actually just return a plain old regular dict at runtime, so this shouldn't lead to any difference in behavior.请注意,执行Some(...)实际上只会在运行时返回一个普通的旧常规字典,因此这不会导致行为上的任何差异。

It could also be worth trying to do:也可能值得尝试:

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

...to see if your editor might give better hints with that form. ...看看您的编辑器是否可以使用该表单提供更好的提示。

I have somewhat narrowed down to a possible solution using the following code.我已经使用以下代码缩小了可能的解决方案。 It meets most of the requirements:它满足大部分要求:

  • mypy type checks passes mypy 类型检查通过
  • shows keys显示键
  • documentation also shows keys and types文档还显示了键和类型
  • The main caviate to this solution is that mypy thinks the value is optional because of a default value so the solution is not quite complete.该解决方案的主要提示是 mypy 认为该值是可选的,因为它具有默认值,因此该解决方案并不完整。

Using the validate_items function, I can validate that the values are there.使用validate_items function,我可以验证这些值是否存在。 Please see the comments on the code snippet and offer suggestions.请查看代码片段的评论并提供建议。

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

在此处输入图像描述

In the screenshot, I can see that mypy is complaining about the None value which is expected, and in the popup help, we can also see the keys that are required in the dictionary being passed along with the type that is being set to it.在屏幕截图中,我可以看到 mypy 正在抱怨预期的None值,并且在弹出帮助中,我们还可以看到字典中所需的键与设置的类型一起传递。

The solution feels quite hacky, and would appreciate any corrections to make it more pythonic.该解决方案感觉非常hacky,并且希望对其进行任何更正以使其更加pythonic。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将字典键与函数关联? - How can I associate dictionary keys with functions? 如何通过将集合作为参数传递来打印字典的键和值? - How can I print the keys and values of a dictionary by passing a set as an argument? 如果我在 Python 中有一个带有 2 个键的字典,我如何实现诸如 mean.median 和variance 之类的函数? - How Can I implement functions like mean.median and variance if I have a dictionary with 2 keys in Python? 当嵌套字典键发生变化时,如何使用嵌套字典查询 mongodb 文档? - How can i query mongodb document with nested dictionaries, when the nested dictionary keys are changing? 如何将 3 个列表映射到字典键 - How can I map 3 lists to dictionary keys 如何向字典添加新键? - How can I add new keys to a dictionary? 如何将位置参数传递给 python 函数中的可选参数? - How can I pass a positional argument to an optional argument in python functions? 如何从嵌套字典创建平面字典,其字符串是引用字典的子集? - How can I create a flat dictionary from a nested dictionary whose keys are a subset of a reference dictionary? 如何添加所有键的值并打印新词典? - How can I add all keys' values and print the new dictionary? 如何将嵌套的字典键转换为字符串? - How can I convert nested dictionary keys to strings?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM