我发现它可以用这种方式或通过抛出__new__
进行子类,没有问题,但类型检查。
class a(tuple):
pass
print(a((1, 2, 3))) # <---- ( 1, 2, 3 )
b: tuple[int, int, int] = a((1, 2, 3)) # <--- Error
# Incompatible types in assignment (expression has type "a", variable has type "Tuple[int, int, int]")
c: tuple = a((1, 2, 3)) # <--- Ok
d: tuple[int, int, int] = (1, 2, 3) # <--- Ok
同样的方式,当你的子类列表将工作。
class a( list[ T ] )
def __init__(self, * pax : T ) : pass
b : list[ int ] = a( 1, 2 ) # <--- Ok
c = a[ int ]( 1, 2 ) # <--- Ok
如何正确地对元组进行子类划分?谢谢你的建议。
您所困惑的问题与子类化无关,而是由于mypy假设任何序列作为参数通过名称传递给任何tuple
及其子类(例如tuple((item, item, ..., item))
,而不是Python元组语法(item, item, ..., item,)
(以具有签名Tuple[Any, ...]
(因为这是默认tuple
构造函数的类型签名(。考虑以下代码示例:
one_tuple: tuple[int] = tuple((1,))
answer: tuple[int] = (1,)
print(one_tuple == answer)
使用python
运行上面的代码将产生输出True
,这就是预期的结果。但是,mypy
将产生以下错误消息:
onetuple.py:1: error: Incompatible types in assignment (expression has type "Tuple[int, ...]", variable has type "Tuple[int]")
Found 1 error in 1 file (checked 1 source file)
考虑到不可能使用Python的标准元组语法来生成其子类的实例(因为它总是生成tuple
(,因此tuple
的任何子类(例如class MyTuple(tuple): ...
(都不能满足任何Tuple[T]
,其中T
不是可变长度的序列。
虽然下面的断言没有在问题中说明,但如果你确信你的tuple
子类将有一些有限的长度,这可能是一个合适的解决方法:
class MyTuple(tuple[int, int, int]):
pass
mytuple: tuple[int, int, int] = MyTuple((1, 2, 3))
在这种情况下,mypy
不会生成任何验证错误。
作为一个附录,随着PEP 646-Variadic Generics的引入,从Python 3.11开始,这可能成为可能,但mypy
还不支持这一点(请参阅GitHub问题Python/mypy#1284 0,在新的打字功能下,PEP 646-截至2022-10-14,还没有跟踪到子问题(,并且pyright
和pyre
似乎没有正确地将语句one_tuple: tuple[int] = tuple((1, 2,))
检查为无效,因此,鉴于我不确定它是否真的正确地支持PEP646,我暂时结束了我的进一步工作。