表示通用类型类的Python类型批注

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

在我的Python 3.7.4代码中,我具有以下功能。

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

我正在努力为klass参数获取类型注释。那不是mypy抱怨的,不是type

错误:“ type”没有属性“ __origin__

我很茫然。正确的注释是什么,有关它的任何[[good文档?

这里是如何使用此功能的示例:

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

python mypy python-typing
2个回答
0
投票
我已经编辑了答案:

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


0
投票
如果您要使用注释中建议的类似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类型化生态系统在很大程度上是为了使静态世界和运行时世界保持分离而设计​​的,因此,将这两个世界混合在一起的机制并不是很方便使用,并且并不总是向后兼容。自例如在Python 3.5中首次发布以来,类型库的内部内容已发生了多次更改。

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