在 Python 中键入类属性的继承

沙哈尔

首先,请看下面的代码:

from typing import Type


class C:
    @staticmethod
    def c_fun():
        return 23


class C1(C):
    @staticmethod
    def c1_fun():
        return 42


class M:
    def __init__(self, c: Type[C]):
        self.c = c()


class M1(M):
    def __init__(self, c: Type[C1]):
        super().__init__(c=c)
        # self.c = c()

    def m1_fun(self):
        print(self.c.c1_fun())

    def show_type(self):
        print(type(self.c))


M1(c=C1).m1_fun()  # Output: 42
M1(c=C1).show_type()  # Output: <class '__main__.C1'>

代码编译并按预期工作,没有任何错误。但是,self.c.c1_fun()在 M1.m1_fun() 中引用时,PyCharm 中的 Python linter会显示以下警告

Unresolved attribute reference 'c1_fun' for class 'C'

虽然它似乎在编译期间解决。为了确保打字self.c,我把它打印出来,在编译过程中似乎是C1。

当我self.c = c()在 M1.__init__() 中取消注释时,linter 警告消失了 - 但我想避免重复,因为它已经在类 M 的构造函数中完成了。

我的问题:

  1. 正如 PyCharm linter 宣称的那样,我做错了什么吗?
  2. 有没有什么好的做法可以在不重复分配的情况下做到这一点?

编辑:我发现了一个类似的问题- 似乎使用 Generic 是要走的路(正如在当前帖子的所选答案中所做的那样)。

山姆怀斯

您可以通过M成为一个Generic类型来完成这项工作,它允许子类(或就此而言是超类的特定实例)缩小c.

from typing import Generic, Type, TypeVar


class C:
    @staticmethod
    def c_fun() -> int:
        return 23


class C1(C):
    @staticmethod
    def c1_fun() -> int:
        return 42


_CType = TypeVar('_CType', bound=C)


class M(Generic[_CType]):
    def __init__(self, c: Type[_CType]) -> None:
        self.c = c()


class M1(M[C1]):
    def __init__(self, c: Type[C1]) -> None:
        super().__init__(c=c)

    def m1_fun(self) -> None:
        print(self.c.c1_fun())

    def show_type(self) -> None:
        print(type(self.c))


M1(c=C1).m1_fun()  # Output: 42
M1(c=C1).show_type()  # Output: <class '__main__.C1'>

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章