Python generic that creates or isinstance 检查它们的类型参数
Python Generic that creates or isinstance checks their type parameter
我想创建一个可以用类型参数化的可继承 class。这是一个没有类型注释的工作示例:
class Simple:
pass
class Bla:
obj_class = Simple
def do(self):
return self.obj_class()
def check(self, x):
return isinstance(x, self.obj_class)
此代码的用户将从 Bla 继承,并且可以设置不同的 obj_class,例如:
class Advanced(Simple):
pass
class Foo(Bla):
obj_class = Advanced
当我想正确键入 annotate this 时,问题就出现了。我想过让 Bla 继承自 Generic[T],其中 T 定义为 TypeVar('T', bound=Simple)
,但是构造函数 T() 和 isinstance 将不起作用,并且还手动将不同的 class 分配给 obj_class 也不行。
这是一个无效示例,因为 T 不能用于非键入上下文:
class Simple:
pass
T = TypeVar('T', bound=Simple)
class Bla(Generic[T]):
def do(self) -> T:
return T()
def check(self, x: Any) -> bool:
return isinstance(x, T)
这是另一个无效示例,由于类型不兼容,我无法将 Simple 分配给 obj_class。
class Simple:
pass
T = TypeVar('T', bound=Simple)
class Bla(Generic[T]):
obj_class: Type[T] = Simple
def do(self) -> T:
return self.obj_class()
def check(self, x: Any) -> bool:
return isinstance(x, self.obj_class)
class Advanced(Simple):
pass
class Foo(Bla):
obj_class = Advanced
有办法解决吗?
你不需要Type[T] = Simple
。
mypy 声明:
Incompatible types in assignment (expression has type "Type[Simple]", variable has type "Type[T]").
您正在尝试将具体类型分配给泛型类型变量。
相反,做类似的事情:
class Simple:
pass
class Advanced(Simple):
pass
class Other:
pass
T = TypeVar('T', bound=Simple)
class Bla(Generic[T]):
obj_class: Type[T]
def do(self) -> T:
return self.obj_class()
def check(self, x: Any) -> bool:
return isinstance(x, self.obj_class)
class SimpleFoo(Bla[Simple]):
obj_class = Simple
class AdvancedFoo(Bla[Advanced]):
obj_class = Advanced
class OtherFoo(Bla[Other]):
obj_class = Other
现在,mypy 正确指出:
error: Type argument "tmp.Other" of "Bla" must be a subtype of "tmp.Simple"
备注
OtherFoo
必须使用特定类型对 Bla
进行子类化,以便 mypy 正确地警告您。
以下不会产生错误:
class OtherFoo(Bla):
obj_class = Other
我想创建一个可以用类型参数化的可继承 class。这是一个没有类型注释的工作示例:
class Simple:
pass
class Bla:
obj_class = Simple
def do(self):
return self.obj_class()
def check(self, x):
return isinstance(x, self.obj_class)
此代码的用户将从 Bla 继承,并且可以设置不同的 obj_class,例如:
class Advanced(Simple):
pass
class Foo(Bla):
obj_class = Advanced
当我想正确键入 annotate this 时,问题就出现了。我想过让 Bla 继承自 Generic[T],其中 T 定义为 TypeVar('T', bound=Simple)
,但是构造函数 T() 和 isinstance 将不起作用,并且还手动将不同的 class 分配给 obj_class 也不行。
这是一个无效示例,因为 T 不能用于非键入上下文:
class Simple:
pass
T = TypeVar('T', bound=Simple)
class Bla(Generic[T]):
def do(self) -> T:
return T()
def check(self, x: Any) -> bool:
return isinstance(x, T)
这是另一个无效示例,由于类型不兼容,我无法将 Simple 分配给 obj_class。
class Simple:
pass
T = TypeVar('T', bound=Simple)
class Bla(Generic[T]):
obj_class: Type[T] = Simple
def do(self) -> T:
return self.obj_class()
def check(self, x: Any) -> bool:
return isinstance(x, self.obj_class)
class Advanced(Simple):
pass
class Foo(Bla):
obj_class = Advanced
有办法解决吗?
你不需要Type[T] = Simple
。
mypy 声明:
Incompatible types in assignment (expression has type "Type[Simple]", variable has type "Type[T]").
您正在尝试将具体类型分配给泛型类型变量。
相反,做类似的事情:
class Simple:
pass
class Advanced(Simple):
pass
class Other:
pass
T = TypeVar('T', bound=Simple)
class Bla(Generic[T]):
obj_class: Type[T]
def do(self) -> T:
return self.obj_class()
def check(self, x: Any) -> bool:
return isinstance(x, self.obj_class)
class SimpleFoo(Bla[Simple]):
obj_class = Simple
class AdvancedFoo(Bla[Advanced]):
obj_class = Advanced
class OtherFoo(Bla[Other]):
obj_class = Other
现在,mypy 正确指出:
error: Type argument "tmp.Other" of "Bla" must be a subtype of "tmp.Simple"
备注
OtherFoo
必须使用特定类型对 Bla
进行子类化,以便 mypy 正确地警告您。
以下不会产生错误:
class OtherFoo(Bla):
obj_class = Other