定义typing.Dict和dict之间的区别?

Sar*_*rit 58 python dictionary type-hinting

我正在练习使用Python 3.5中的类型提示.我的一位同事使用typing.Dict:

import typing


def change_bandwidths(new_bandwidths: typing.Dict,
                      user_id: int,
                      user_name: str) -> bool:
    print(new_bandwidths, user_id, user_name)
    return False


def my_change_bandwidths(new_bandwidths: dict,
                         user_id: int,
                         user_name: str) ->bool:
    print(new_bandwidths, user_id, user_name)
    return True


def main():
    my_id, my_name = 23, "Tiras"
    simple_dict = {"Hello": "Moon"}
    change_bandwidths(simple_dict, my_id, my_name)
    new_dict = {"new": "energy source"}
    my_change_bandwidths(new_dict, my_id, my_name)

if __name__ == "__main__":
    main()
Run Code Online (Sandbox Code Playgroud)

它们都工作得很好,似乎没有区别.

我已经阅读了typing模块文档.

之间typing.Dictdict哪一个,我应该在程序中使用?

Mar*_*ers 76

使用普通typing.Dict和没有真正区别dict.

然而,typing.Dict是一个泛型类型,让你指定键和值的类型太多,使之更加灵活:

def change_bandwidths(new_bandwidths: typing.Dict[str, str],
                      user_id: int,
                      user_name: str) -> bool:
Run Code Online (Sandbox Code Playgroud)

因此,很可能在项目生命周期中的某个时刻,您需要更精确地定义字典参数,此时扩展typing.Dicttyping.Dict[key_type, value_type]"更小"的更改而非替换dict.

您可以通过在此处使用Mapping或输入来使其更加通用MutableMapping; 因为你的功能不需要改变映射,我会坚持Mapping.A dict是一个映射,但您可以创建其他也满足映射接口的对象,并且您的函数可能仍然适用于:

def change_bandwidths(new_bandwidths: typing.Mapping[str, str],
                      user_id: int,
                      user_name: str) -> bool:
Run Code Online (Sandbox Code Playgroud)

现在你清楚地告诉其他用户这个函数你的代码实际上不会改变new_bandwidths传入的映射.

您的实际实现只是期望一个可打印的对象.这可能是一个测试实现,但是如果你使用的话new_bandwidths: typing.Any,你的代码会继续工作,因为Python中的任何对象都是可打印的.

  • 根据打字文档中的示例 `dict[str, str]` 也是有效的,请参阅:https://docs.python.org/3/library/typing.html#type-aliases (6认同)
  • 有用的附加示例是当字典值可以是不同类型时,例如 `{"name": "bob", "age" : 51}`,这会是类似 `typing.Mapping[Union[str, int]` 吗?那么像 `{"person": {"name":"bob", "age": 51}` 这样的嵌套字典会像 `typing.Mapping[str, typing.Mapping[Union[str, int]] ]`?像这样使用“Union”让我很烦恼,因为它不是一个严格的模式,因为没有排序。也许那没问题,或者有其他选择吗? (2认同)
  • 这似乎非常有趣、有用且相关https://www.python.org/dev/peps/pep-0589/ (2认同)
  • @GregHilston:啊,是的,是的。 (2认同)

AKS*_*AKS 19

typing.Dict是以下的通用版本dict:

class typing.Dict(dict, MutableMapping[KT, VT])

dict的通用版本.此类型的用法如下:

def get_position_in_index(word_list: Dict[str, int], word: str) -> int:
     return word_list[word]
Run Code Online (Sandbox Code Playgroud)

在这里,您可以在dict中指定键的类型和值: Dict[str, int]


Ehs*_*dar 16

正如python 组织中所说

类打字.Dict(dict, MutableMapping[KT, VT])

dict 的通用版本。对于注释返回类型很有用。要注释参数,最好使用抽象集合类型,例如映射。

该类型可以如下使用:

def count_words(text: str) -> Dict[str, int]:
    ...
Run Code Online (Sandbox Code Playgroud)

dict不太通用,您将能够更改传入的映射。事实上,python.Dict您可以指定更多详细信息。

另一个提示:

自 3.9 版起已弃用:builtins.dict 现在支持 []。请参阅PEP 585 和通用别名类型。

  • 非常好地指出“typing.Dict”的弃用。 (6认同)

sno*_*ton 7

如果您来自 google for TypeError: Too few parameters for typing.Dict; actual 1, expected 2,则需要提供键和值的类型。

所以,Dict[str, str]而不是Dict[str]