社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

在Python中为类属性键入继承性

Shahar • 3 年前 • 1335 次点击  

首先,请查看以下代码:

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'>

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

Unresolved attribute reference 'c1_fun' for class 'C'

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

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

我的问题是:

  1. 我做错了什么吗,就像皮查姆·林特所说的那样?
  2. 有没有不重复作业的好方法?

编辑: 我找到了一个 similar question -似乎使用泛型是一种方式(正如在当前帖子的选择答案中所做的那样)。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/132270
 
1335 次点击  
文章 [ 1 ]  |  最新文章 3 年前
Samwise
Reply   •   1 楼
Samwise    3 年前

你可以通过 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'>