【问题标题】:Python: Initialising a new derived class in a method of a base classPython:在基类的方法中初始化新的派生类
【发布时间】:2016-06-29 08:38:09
【问题描述】:

我的情况是我可以访问两个可以很好地协同工作的类。广泛修改他们的代码可能是不可能的,但也许可以实现小的更改。但是,我想对这两个类进行一些小的扩展。这似乎是一项子类化、从每个类派生并添加功能的工作。但是我遇到了一个问题,因为一个基类调用了另一个,而不是我的派生类。

假设我在模块“base_classes.py”中有两个类 A 和 B。 B 类有一个方法可以创建 A 类的实例并使用它,例如

'base_classes.py'

class A():
    def __init__(self):
        print('Class A being called')

class B():
    def __init__(self):
        self.do_thing()
    def do_thing(self):
        self.myA = A() # Here class A is explicitly named

所以我想继承这两个并扩展它们。我在一个单独的模块中这样做:

'extensions.py'

import base_classes

class DerivedA(base_classes.A):
    def __init__(self):
        super().__init__()
        print('Class DerivedA being called')

class DerivedB(base_classes.B):
    pass

db = DerivedB()

正如预期的那样,输出很简单

Class A being called  

但是如何防止 我的 B 的子类 在方法 do_thing(self) 中创建 A 的基类的实例,而是创建 DerivedA 的实例?

简单的方法是在 DerivedB 中覆盖 do_thing(self),以便它显式调用 DerivedA,例如

class DerivedB(base_classes.B):
    def do_thing(self):
        self.myA = DerivedA() # Here class DerivedA is explicitly named

对于这个小例子来说这很好,但是如果do_thing(self) 有一百行长并且包含许多 A 类型的对象呢?如果 B 中的大多数方法都包含一些 A 对象怎么办。您基本上必须用几乎精确的副本覆盖每个方法,这使得首先从 B 派生毫无意义。就我而言,这几乎就是问题所在,我认为必须有一种聪明的 Pythonic 方法来解决这个问题。理想情况下无需完全重写原始类。

有什么想法吗?

【问题讨论】:

  • 您需要DeriveB 必须调用DeriveA 的某种信息。它可以是名称或B.__init__(DerivedA) 的参数。这里有很多方法。

标签: python inheritance subclass derived-class


【解决方案1】:

您可以更改 B 类的 do_thing 方法并在参数中传递一个类:

class B():
    def __init__(self):
        self.do_thing()
    def do_thing(self, klass=A):
        self.myA = klass()

那么derivedBdo_thing方法就可以用DerivedA调用了

class DerivedB(base_classes.B):
    def do_thing(self, klass=DerivedA):
        return super(DerivedB, self).do_thing(klass)

【讨论】:

  • 或者信息可以在类属性self.__class__.do_thing_class
  • 嗯,好的。我希望我可以完全不改变基类而侥幸逃脱。但这似乎相当小。谢谢
猜你喜欢
  • 1970-01-01
  • 2022-12-03
  • 2010-11-10
  • 2020-08-19
  • 1970-01-01
  • 2019-05-21
  • 2015-06-19
  • 2023-03-31
  • 1970-01-01
相关资源
最近更新 更多