微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从带有类型参数的typing.Union 派生

如何解决从带有类型参数的typing.Union 派生

我正在尝试从 typing.Union 派生一个类,使用类型参数进行参数化,但我收到了一个我不明白的 TypeError。

这些都很好:

import typing

class Foo(typing.Dict[str,int]): pass
class Bar(typing.Union[str]): pass
typing.Union[str,int]

(当然,Union[str] 是多余的,可以只是 str。)

但以下引发 TypeError: __init__() takes 2 positional arguments but 4 were given

class Foo(typing.Union[str,int]): pass

class Foo(typing.Optional[str]) 引发相同的错误,这是有道理的,因为 typing.Optional[str] 等价于 typing.Union[nonetype,str]

另一方面,如果有某种原因要避免子类化 Union 而子类化 DictList 很好(我在 {{3 }}),我想知道它是什么。

解决方法

According to the docs,您不能子类化或实例化联合。

class Foo(typing.Union[str,int]):
    pass

def f(foo: Foo):
    print(foo)
    
f(1)

加注

Traceback (most recent call last):
  File "<string>",line 3,in <module>
File "/usr/lib/python3.8/typing.py",line 317,in __new__
    raise TypeError(f"Cannot subclass {cls!r}")
TypeError: Cannot subclass <class 'typing._SpecialForm'>

相反,您可以创建类型别名:

Foo = typing.Union[str,int]

def f(foo: Foo):
    print(foo)
    
f(1)

按预期工作。


你可能会问为什么

class Bar(typing.Union[str]):
    pass

有效。如果您在创建 (typing.Union) 时查看 __new__at the source code,您将看到以下代码段:

if origin is Union:
    parameters = _remove_dups_flatten(parameters)
    # It's not a union if there's only one type left.
    if len(parameters) == 1:
        return parameters[0]

这意味着,如果一个 typing.Union 有一个单一类型,它将等同于这个类型。事实上,

print(isinstance(Bar(),str))

输出为真。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。