【问题标题】:Python Generic that creates or isinstance checks their type parameter创建或 isinstance 的 Python 泛型检查其类型参数
【发布时间】:2021-10-22 12:11:12
【问题描述】:

我想创建一个可以用类型参数化的可继承类。这是一个没有类型注释的工作示例:

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

当我想正确输入注释时问题就开始了。我想过让 Bla 从 Generic[T] 继承,其中 T 定义为TypeVar('T', bound=Simple),但随后构造函数 T() 和 isinstance 将不起作用,并且手动为 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

有没有办法解决这个问题?

【问题讨论】:

    标签: python generics typing


    【解决方案1】:

    你不需要Type[T] = Simple

    mypy 状态:

    赋值中的类型不兼容(表达式的类型为“Type[Simple]”,变量的类型为“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 正确地指出:

    错误:“Bla”的类型参数“tmp.Other”必须是“tmp.Simple”的子类型

    注意

    OtherFoo 必须将 Bla 子类化为特定类型,以便 mypy 正确警告您。

    以下不会产生错误:

    class OtherFoo(Bla):
        obj_class = Other
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-25
      • 1970-01-01
      • 2011-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多