扩展超类的所有子类

2024-04-25 22:39:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个一对多类继承结构,如下所示:

class SuperClass:
  def func1():
    print 'hello'

  def func2():
    print 'ow'

class SubClass1(SuperClass):
   def func1():
     print 'hi'

class SubClass2(SuperClass):
   def func1():
     print 'howdy'

...

我想向类A添加功能,以便在创建类B和C(等等)时使用它,但我不能直接编辑类A的代码。我目前的解决方案是:

def func3():
  print 'yes!'

SuperClass.func3 = func3

有没有一个更好和/或更多的方法来实现这一点?你知道吗


Tags: 功能hellodefhi结构classprintsuperclass
1条回答
网友
1楼 · 发布于 2024-04-25 22:39:17

这被称为“monkeypatching”,在某些情况下是完全合理的。你知道吗

例如,如果您必须使用其他依赖于SuperClass的代码(您无法修改),并且您需要更改该代码的行为,那么您唯一真正的选择就是替换SuperClass上的方法。你知道吗


然而,在你的情况下,似乎没有任何好的理由这样做。您正在定义SuperClass的所有子类,那么为什么不在它们之间添加另一个类呢?你知道吗

class Intermediate(SuperClass):
    def func3():
        pass

class SubClass1(Intermediate):
    def func1():
        print 'hi'

对于“本应在SuperClass中的功能来说,这还不够好,但如果其他无法控制的代码需要该功能,就不是了……但是当只有您的代码需要该功能时,它同样好,而且简单得多。你知道吗


即使子类不在您的控制之下,通常您也可以从的每个类派生一个新类。例如:

class Func3Mixin(object):
    def func3():
        pass

class F3SubClass1(SubClass1, Func3Mixin):
    pass

class F3SubClass2(SubClass2, Func3Mixin):
    pass

现在只需构造F3SubClass1的实例,而不是SubClass1。需要SubClass1实例的代码可以很好地使用F3SubClass1。Python的duck类型使得这种“面向mixin的编程”特别简单:在Func3Mixin.func3的实现中,您可以使用SuperClass的属性和方法,尽管Func3Mixin本身与SuperClass没有任何静态关系,因为您知道任何作为Func3Mixin的运行时对象也将是SuperClass。你知道吗


同时,即使monkeypatching是合适的,它也不一定是最好的答案。例如,如果您正在修补某些第三方代码中的一个bug,该代码有一个很好的许可证和一个源代码库,可以很容易地维护您自己的修补程序,您只需将其分叉,创建一个固定的副本,并使用它而不是原始的。你知道吗


另外,值得指出的是,没有一个类在编写时是实际可用的,任何调用任何方法的尝试都会引发TypeError,因为它们缺少self参数。但是你在func3中进行monkeypatch的方式,它将以与func1完全相同的方式失败。(我在上面所画的备选方案也是如此。)


最后,这里所有的类都是经典类而不是新样式的,因为您忘记了让SuperClassobject继承。当然,如果你不能改变SuperClass,那不是你的错,但是你可能想通过让你的子类(或者Intermediate)从objectSuperClass乘继承来修复它。(如果你一直在关注:是的,这意味着你可以融入新的风格和档次。尽管在封面下,你必须理解元类才能理解原因。)

相关问题 更多 >

    热门问题