使用类型参数从 typing.Union 派生
Deriving from typing.Union with type arguments
我正在尝试从 typing.Union
派生一个 class,使用类型参数进行参数化,但我收到一个我不理解的 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]
.
另一方面,如果有某些原因需要避免 subclassing Union
而 subclassing Dict
或 List
很好(我在 this portion of the Mypy docs 之后模糊地建模我的代码),我想知道它是什么。
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
创建时查看 at the source code (__new__
),您将看到以下代码段:
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))
输出真。
我正在尝试从 typing.Union
派生一个 class,使用类型参数进行参数化,但我收到一个我不理解的 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]
.
另一方面,如果有某些原因需要避免 subclassing Union
而 subclassing Dict
或 List
很好(我在 this portion of the Mypy docs 之后模糊地建模我的代码),我想知道它是什么。
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
创建时查看 at the source code (__new__
),您将看到以下代码段:
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))
输出真。