【问题标题】:How to create new subclasses by adding the same method to multiple classes如何通过向多个类添加相同的方法来创建新的子类
【发布时间】:2019-02-04 18:14:47
【问题描述】:

我有 5 个类都是父类的子类。我想通过为每个类添加相同的方法来为每个类定义新的子类。有没有办法动态地做到这一点?这在 OOP 术语中有名称吗?

下面的new_method 对所有情况都完全相同,所以我想重复一遍。

class A(MySuperClass)
class B(MySuperClass)
class C(MySuperClass)
class D(MySuperClass)

class AAA(A):

    def new_method():
        ...

class BBB(B):

    def new_method():
        ...

class CCC(C):

    def new_method():
        ...

class DDD(D):

    def new_method():
        ...

【问题讨论】:

    标签: python oop inheritance


    【解决方案1】:

    您可以通过创建包含new_method 的新类来解决重复问题,如下所示:

    class A(MySuperClass)
    class B(MySuperClass)
    class C(MySuperClass)
    class D(MySuperClass)
    
    class Mixin():
        def new_method():
            pass
    
    class AAA(A, Mixin):
        pass
    

    这称为多继承。您可以在这里将继承视为专业化机制和代码共享。

    【讨论】:

      【解决方案2】:

      除了多重继承,如果你的代码更方便,你也可以使用装饰器:

      def add_new_method(cls):
          def new_method(self, ...):
              pass
          cls.new_method = new_method
          return cls
      
      @add_new_method
      class AAA(A):
          ...
      

      但是,如果您不一定需要一个新的AAA 子类,而只是想从超类中将new_method 添加到A, B, C, D,那么很简单:

      def new_method(self, ...):
          pass
      
      A.new_method = new_method
      

      甚至更好。如果MySuperClass可以更改,您可以这样做:

      MySuperClass.new_method = new_method
      
      # A, B, C and D will all have new_method automatically.
      

      【讨论】:

      • 这很有趣。我仍然围绕着装饰器。我是否认为当你装饰一个类时,装饰会立即发生,而不是在创建类的实例时发生?在您的示例中,装饰器接收实际的类而不是类的实例,对吗?
      • 是的,它们在定义之后立即被修饰。请参阅我今天早些时候回答的这个相关问题:stackoverflow.com/questions/54517806/…。是的,装饰发生在类上,而不是实例上。
      【解决方案3】:

      您可以使用type 动态创建类:

      class Foo(object):
          def __init__(self):
              print("NOTHING")
      
      def func(self):
          print("ARRRGH")
      
      Bar = type('Bar', (Foo,), {"func": func})
      Bar2 = type('Bar2', (Foo,), {"func": func})
      Bar3 = ... # Put in loop if you like.
      
      b = Bar() # This will print "NOTHING", Bar2, Bar3 works the same way.
      b.func() # will print "ARRRGH"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-05
        • 1970-01-01
        • 2012-10-10
        • 1970-01-01
        • 2019-02-26
        相关资源
        最近更新 更多