根据
文档
,“内置泛型类型..作为类型和基类都是有效的。” 它给出了一个源自
Dict[str, List[Node]]
的示例。
但是,当我使用
Tuple[int, int]
尝试此操作时,构造函数无法正确转发。 例如:
from typing import Tuple
class MyTuple(Tuple[int, int]):
def hello(self):
print("hello: " + str(len(self)))
MyTuple([1, 2]).hello()
打印
hello: 0
如果我从内置
tuple
派生,它会打印
hello: 2
从
tuple
派生时如何初始化基本
Tuple[int, int]
对象?
不能直接使用
tuple
构造函数初始化
typing.Tuple
的子类,因为
typing.Tuple
只是一个类型提示,而不是实际的类。它在运行时被 Python 解释器擦除,并替换为
tuple
。
为了解决这个问题,需要重写
__new__
方法,该方法是创建 Python 对象的机制:
from typing import Tuple
class MyTuple(Tuple[int, int]):
def __new__(cls, *args):
return super().__new__(cls, args)
def hello(self):
print("hello: " + str(len(self)))
MyTuple([1, 2]).hello() # 输出:hello: 2
在这个例子中:
-
我们定义了
__new__
方法,该方法接收cls
(类本身)和*args
(传递给构造函数的参数)。 -
在
__new__
方法内部,我们使用super().__new__(cls, args)
创建一个新的tuple
对象,并将参数传递给它。这确保了底层tuple
对象被正确初始化。 -
现在,
MyTuple([1, 2])
将正确创建一个包含两个整数的MyTuple
实例,并且hello
方法将按预期工作。
注意:
虽然可以从
typing.Tuple
派生子类,但通常最好将
tuple
用作不可变数据的简单容器,并专注于为的用例创建单独的类或使用其他数据结构。