【问题标题】:Using subclass variables in base class methods在基类方法中使用子类变量
【发布时间】:2021-10-15 14:31:26
【问题描述】:

我想知道在基类方法中使用子类变量(本例中为self.sub_resource)的常用方法是什么?

版本 1 和 2 似乎工作方式相同,但版本 1 代码较少,但 self.sub_resource 在 pycharm 中以 Unresolved attribute reference 'sub_resource' for class 'Base' 突出显示

那么哪种变体更可取?还有其他优点/缺点吗?

# Version 1:

    class Base():
        def __init__(self):
            self.base_resource = 'Base.resource'

            print('Base.__init__')

        def predict(self):
            print('Base.predict() start')

            self.forward()

            print('Used in Base.predict():', self.base_resource)
            print('Used in Base.predict():', self.sub_resource)

            print('Base.predict() end')

        def forward(self):
            raise NotImplementedError

    class A(Base):
        def __init__(self):
            super().__init__()

            self.sub_resource = 'A.sub_resource'

            print('A.__init__')

        def forward(self):
            print('A.forward() start')
            print('Used in A.forward():', self.base_resource)
            print('Used in A.forward():', self.sub_resource)
            print('A.forward() end')

    print('-' * 60)
    a = A()
    a.predict()

# Version 2:

    class Base():
        def __init__(self, sub_resource):
            self.sub_resource = sub_resource
            self.base_resource = 'Base.resource'

            print('Base.__init__')

        def predict(self):
            print('Base.predict() start')

            self.forward()

            print('Used in Base.predict():', self.base_resource)
            print('Used in Base.predict():', self.sub_resource)

            print('Base.predict() end')

        def forward(self):
            raise NotImplementedError

    class A(Base):
        def __init__(self):
            self.sub_resource = 'A.sub_resource'

            super().__init__(self.sub_resource)

            print('A.__init__')

        def forward(self):
            print('A.forward() start')
            print('Used in A.forward():', self.base_resource)
            print('Used in A.forward():', self.sub_resource)
            print('A.forward() end')

    print('-' * 60)
    a = A()
    a.predict()

【问题讨论】:

  • 在第二个例子中,为什么你在子类中设置属性然后调用超类立即重置它?首先,没有什么可以保证每个子类都设置属性,所以警告是正确的。如果基类不能单独工作,则应为abstract,并在其中表达对子类的要求。

标签: python-3.x oop


【解决方案1】:

第 2 版是正确的做法。这允许子类在不声明 sub_resource 属性的情况下扩展 Base 类。

解释器需要确保该属性存在。这就是为什么 pycharm 在版本 1 中突出显示了这一行。在执行期间子类值将优先于基类。

最好在基类中声明所有访问的属性,然后在必要时在子类中覆盖它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-05
    • 1970-01-01
    • 1970-01-01
    • 2012-05-05
    • 2021-12-15
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多