表示泛型类型类的Python类型注释是什么

2024-04-24 22:02:49 发布

您现在位置:Python中文网/ 问答频道 /正文

在我的python3.7.4代码中,我有以下函数。你知道吗

def is_dict(klass: ???) -> bool:
    return klass.__origin__ == dict

我正在努力为klass参数获取正确的类型注释。这不是type,因为mypy抱怨。你知道吗

error: "type" has no attribute "__origin__"

我不知所措。正确的注释是什么?是否有好的文档?你知道吗

下面是如何使用此函数的示例:

>>> is_dict(typing.Dict[str, int])
True
>>> is_dict(typing.List[str])
False

Tags: 函数代码typing类型参数returnisdef
2条回答

我编辑了答案:

import typing

def is_dict(klass: typing.GenericMeta) -> bool:
    return klass.__origin__ == typing.Dict

if __name__ == "__main__":
    print(is_dict(typing.Dict[str, int]))
    print(is_dict(typing.List[str]))

或者:

def is_dict(klass: typing.GenericMeta) -> bool:
        return klass.__orig_bases__[0] == dict

如果您想使用注释中建议的GenericMeta之类的东西,或者尝试创建一个自定义的protocol来定义适当的__origin__属性,您首先需要更新typeshed中类型模块的类型提示来定义这些属性。你知道吗

不过,目前我建议只使用Type[Any]Type[object]。你知道吗

from typing import Type, Any

# If you want to make minimal modifications to your code, make
# 'klass' dynamically typed.
def is_dict_1(klass: Type[Any]) -> bool:
    return klass.__origin__ == dict

# If you want to make your code robust, assume nothing about 'klass'
# except that it's some sort of type and verify the attribute you're
# about to use exists.
def is_dict_2(klass: Type[object]) -> bool:
    return getattr(klass, '__origin__', None) == dict

如果您正试图直接操作类型提示表达式,因为您正试图创建某种序列化/反序列化库,那么您还可以尝试查看像pydantic这样的库的源代码以获得灵感。你知道吗

更广泛地说,我还建议您尽可能减少代码中将类型提示表达式作为运行时实体进行操作的位置。Python类型化生态系统在很大程度上是为了保持静态世界和运行时世界的分离而设计的,因此混合这两个世界的机制实际上并不那么方便使用,而且并不总是向后兼容的。例如,自从python3.5首次发布以来,类型库内部已经发生了多次更改。你知道吗

相关问题 更多 >