【问题标题】:Python: multi level inheritancePython:多级继承
【发布时间】:2016-05-18 04:18:33
【问题描述】:

我很难找到 Python 继承问题的有效解决方案。

所以存在如下代码:

class Foo( object ):
        def __init__():
                self.some_vars
        def foo_func():
                x = Bar()
        def foo_bar_func()
                x += 1

class Fighters( Foo ):
        def __init__():
                Foo.__init__()
        def func1():
                Foo.some_attribute
        def func2():
                Foo.someother_func()

class Bar():
        def bar_func():
                #some stuff here

问题在于我需要覆盖Bar.bar_func(),但这有两个层次。我通过执行以下操作解决了它:

class Foo( Foo ):
        def __init__():
                Foo.__init__()
        def foo_func():          #Overridden method
                x = myBar()   

class myFighters( Foo ):
        def __init__():
                Foo.__init__()
        def func1():
                Foo.some_attribute
        def func2():
                Foo.someother_func()

class myBar():
        def bar_func():      #the function that I actually need to change
                #my sweet code here

实际上唯一不同的是myBar.bar_func(),但我必须至少做两件我认为丑陋的事情。

一个是我必须创建一个继承自Fooclass Foo。这似乎是一件奇怪的事情,并且不会让事情变得很清楚。我这样做是为了避免将myFighters 中的每个引用从Foo 重命名为myFoo

第二个是我必须将所有代码从Fighters 复制到myFighters 中,唯一的目的是在Bar() 中使用覆盖函数。 FightersmyFighters 完全相同,除了 Fighters 使用调用 Bar()FoomyFighters 使用调用 myBar()Foo。有没有人有任何建议来解决这两个问题?或者我应该庆幸我找到了解决方案并继续我的生活......

【问题讨论】:

    标签: python oop inheritance multi-level


    【解决方案1】:

    经过一些代码清理以制作可运行的示例:

    class Foo( object ):
            def __init__(self):
                    print("foo init")
                    self.foo_func()
            def foo_func(self):
                    print("making bar")
                    self.x = Bar()
            def foo_bar_func(self):
                    self.x.bar_func()
    
    class Fighters( Foo ):
            def __init__(self):
                    print("fighters init")
                    Foo.__init__(self)
            def func1(self):
                    Foo.some_attribute
            def func2(self):
                    Foo.someother_func()
    
    class Bar(object):
            def __init__(self):
                    print("bar init")
            def bar_func(self):
                    #some stuff here
                    print("bar bar_func")
    

    实例化一个原始战士:

    f1 = Fighters()
    f1.foo_bar_func()
    

    它从原始 bar 类调用方法:

    fighters init
    foo init
    making bar
    bar init
    bar bar_func
    

    现在我们可以用 MyFighters 子类 Fighters 和用 MyBar 子类 Bar。重写 Foo 类的 foo_func 是 MyFighters 并调用 MyBar 的构造函数,它可以执行您想要的操作,而无需复制方法:

    class MyFighters(Fighters):
            def foo_func(self):
                    print("making mybar")
                    self.x = MyBar()
    
    class MyBar(Bar):
            def bar_func(self):
                    print("mybar bar_func")
    

    当我们创建一个新的战斗机时:

    f2 = MyFighters()
    f2.foo_bar_func()
    

    我们看到它调用了新 bar 类的方法:

    fighters init
    foo init
    making mybar
    bar init
    mybar bar_func
    

    很明显,这只是因为创建 Bar 对象的方法对于子类化和替换是微不足道的。通常情况并非如此,因为它可能会直接在 init 中完成,而不是调用方法来完成。所以原始类的设计是允许这个示例运行的原因。

    【讨论】:

      【解决方案2】:

      类上定义的所有方法都将实例作为第一个参数。约定是调用实例self 并这样引用它:

      class Foo(object):
          def __init__(self):
              self.x = 1
      

      其次,如果不需要覆盖父类的方法,直接省略即可:

      class Fighters(Foo):
          # __init__ would be here, but I leave it out to inherit the method
      
          def func_1(self):
              ...
      

      最后,如果要引用父母的行为,请使用super()

      class MyFighters(Fighters):
          def __init__(self):
               super(MyFighters, self).__init__()
               self.y = 2
      

      另请参阅 this examplethe official Python docs on classes

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多