【问题标题】:accessing type of typing.List访问类型的类型。列表
【发布时间】:2019-01-27 22:35:33
【问题描述】:

我目前正在编写代码,需要知道给定类型注释是否是可迭代的(例如ta = typing.List[str]

我期待着……像这样工作:

if isinstance(ta, typing.List):
    # do s.th.

然而,ta 的类型是typing._GenericAlias,这与typing.List 没有太大关系。

相反,我必须像这样使用“origin”属性:

if getattr(ta, '__origin__', None) == list:
    # do s.th.

这真的是正确的做法吗?

【问题讨论】:

  • 好吧,考虑一下isinstance(list, Iterable) 类似地 行不通...
  • 我知道的三个可迭代实例是list,str,and dict,还有其他的吗?就做if isinstance(ta, (list,str,dict)):
  • 但 ta 不是实际的可迭代对象,它是类型提示 typing.List。换种说法:我很困惑,因为isinstance(List[str], List) 返回 false...
  • 出于好奇,您到底想做什么?类型提示在运行时基本上是不可见的——在运行时自省类型提示本身并不是一个得到很好支持或常见的用例。
  • 我正在使用 python3.7 数据类,并且喜欢从 dict 中初始化它 - 具有嵌套结构。 @dataclass class Foo x: typing.List(Bar) 因为我有许多嵌套结构(我从 dict 初始化),所以我不想为每个嵌套属性编写单独的 __post_init__ 例程,而是编写一个新的装饰器(例如nested_dataclass) 动态创建属性数据类(受stackoverflow.com/questions/51564841/… 启发 - 完全忽略了这一点)

标签: python-3.x typing


【解决方案1】:

在 CPython 3.8 中:

from typing import_GenericAlias

# Now, let's suppose that you have a class "cls"
name = "your_attribute"
typ = cls.__annotations__[name]
if isinstance(typ, _GenericAlias) and typ._name == "List":
    print("This is a list type")

_GenericAlias 是未记录的受保护/生成的类。这是一个实现细节。我不知道在运行时访问类型信息的任何可靠方法。

【讨论】:

  • 这不是问题,但您可能会发现marshmallow.readthedocs.io/en/stable 更适合您的需求。它在 GitHub 上有 4500 多颗星。还有其他类似的库提供运行时类型信息。 (但是你可能会在你的 IDE 中放松类型检查。)
猜你喜欢
  • 1970-01-01
  • 2010-10-07
  • 1970-01-01
  • 1970-01-01
  • 2021-04-09
  • 1970-01-01
  • 2018-07-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多