我想定义一种"包装器"泛型类型,比如MyType[T]
,这样它就具有与包装类型相同的类型接口.
from typing import Generic, TypeVar
T = TypeVar("T")
class MyType(Generic):
pass # what to write here?
因此,举个例子,当我有一个类型为MyType[int]
的时候,类型判断器应该把它当作一个int
类型来处理.
这有可能吗?如果是这样的话,是如何做到的呢?
我想定义一种"包装器"泛型类型,比如MyType[T]
,这样它就具有与包装类型相同的类型接口.
from typing import Generic, TypeVar
T = TypeVar("T")
class MyType(Generic):
pass # what to write here?
因此,举个例子,当我有一个类型为MyType[int]
的时候,类型判断器应该把它当作一个int
类型来处理.
这有可能吗?如果是这样的话,是如何做到的呢?
为了确认,您希望表达式MyType[T]
表示静态类型判断器"MyType
和T
的子类",这样声明
class MyType:
attr: object
将产生以下结果(例如,以mypy和int.conjugate
为例):
>>> reveal_type(MyType[int].conjugate) # def (self: builtins.int) -> builtins.int
>>> obj: MyType[int] = MyType[int]()
>>> reveal_type(obj.attr) # builtins.object
不,这不是Python类型中支持的习惯用法.您的用例应该包含在future 的intersection types实现中,并且建议使用MyType & T
的语法.
对于静态类型判断器,语法MyType[T]
意味着and only means,MyType
是generic type(包括generic structural types),MyType
拥有的API派生自任何元类、任何基类以及在class MyType
‘S主体下声明的任何内容.
任何类型参数化(例如,在MyType[T]
中将int
传递到T
)只影响类基中的泛型类型和类体中的语句;
在告诉静态类型判断器类从另一个类继承API的类体中没有什么可以写的,因为这个信息已经由元类和基类给出;
只有当<type>
是用户定义的泛型类型时,<type>[T]
才被明确定义为statically-inferrable type.从其他任意try 使<type>[T]
成为有效表达式而推断出的静态类型是不稳定的,并且是实现定义的,与运行时实现无关.
from typing import *
T = TypeVar("T")
class M(type):
def __getitem__(cls, type_: T, /) -> T: ...
class A(metaclass=M): ...
class B:
def __class_getitem__(cls, type_: T, /) -> T: ...
class C(Generic[T]): ...
>>> A_int: TypeAlias = A[int] # mypy: "A" expects no type arguments, but 1 given # pyright: Expected no type arguments for class "A"
>>> B_int: TypeAlias = B[int] # mypy: "B" expects no type arguments, but 1 given # pyright: <no messages>
>>> C_int: TypeAlias = C[int]
>>>
>>> reveal_type(A[int]) # mypy: <overloads of `int.__new__`> pyright: Type of "A[int]" is "Type[int]"
>>> reveal_type(B[int]) # mypy: The type "type[B]" is not generic and not indexable pyright: Type of "B[int]" is "Type[int]"
>>> reveal_type(C[int]) # mypy: Revealed type is "def () -> __main__.C[builtins.int]" pyright: Type of "C[int]" is "Type[C[int]]"