【问题标题】:Classses, inheritance and methods/functions in PythonPython 中的类、继承和方法/函数
【发布时间】:2019-03-28 10:45:49
【问题描述】:

目前,我的项目结构如下:

main.py
-------

class main_fun(object):
    def __init__(self, <parameters>):


ops.py
------

class ops_fun(main_fun):
    def __init__(self):
        super(ops_fun, self).__init__(<parameters>)

它基本上翻译成以下内容:

                              ------------------
                              main_fun (main.py)
                              ------------------
                                      |
                                      |
                               ----------------
                               ops_fun (ops.py)
                               ----------------

我想将以上内容拆分/重组为以下内容:

                              ------------------
                              main_fun (main.py)
                              ------------------
                            /         |          \
                           /          |           \
        ----------------     ----------------      ----------------
        AuxOps (aops.py) === CoreOps (cops.py) === DerOps (dops.py)
        ----------------     ----------------      ----------------
                           \          |           /
                            \         |          /
                              ------------------
                              con_fun (contf.py)
                              ------------------

这基本上意味着我想要:

  1. 将类main_fun中的所有方法/函数和变量继承到AuxOpsCoreOpsDerOpscon_fun中的每一个。
  2. AuxOpsCoreOpsDerOps 中实现了不同的方法/功能,应该在彼此的类中继承。即AuxOps应该继承CoreOpsDerOps中的每个方法,DerOps应该继承CoreOpsAuxOps中的每个方法。
  3. con_fun 中继承AuxOpsCoreOpsDerOps(继承这些会自动继承main_fun,因为它是它们的父级吗?)。

我怎样才能实现上述目标?

【问题讨论】:

  • 我是多继承的新手,但你能试试这个:```` class con_fun(AuxOps,CoreOps,DerOps): pass ````

标签: python python-2.7 class inheritance


【解决方案1】:

Python允许多重继承,所以你可以直接

class Parent ...

class ChildA(Parent) ...
class ChildB(Parent)...

class Grandchild(ChildA, ChildB)...

子继承其所有父方法。这导致Grandchild 将通过双亲继承Parent 类的方法的问题。默认情况下,当被要求调用该方法时,python 会首先查看最左边的父类。

更多细节请查看钻石问题python的方法解析顺序

【讨论】:

  • 那么,对于 ChildA 类,我可以做 class ChildA(Parent, ChildB, ChildC) 以便 ChildBChildC 的所有方法都继承给它。同样对于ChildBChildC?如果是,这是一个好习惯吗?
  • 差不多。如果 ChildA 继承自 ChildB,则 ChildB 不能继承自 ChildA。您必须从图表中较高的类继承,不能从同一级别的类继承。
【解决方案2】:

一个自以为是的答案。我建议使用基类和插件来编写。通用类的多重继承可能是一个非常痛苦的调试。

class AuxPlugin( object):
    def auxMethod1( self, ...)

    ...

class CorePlugin( object)
    def coreMethod1( self, ...)
    ...

class DerPlugin( object)
    def derMethod1( self, ...)
    ...

class AuxOps( AuxPlugin, Main_Fun):  # better, call Main_Fun Base_whatever
    pass
class CoreOps( CorePlugin, Main_Fun):  
    pass
class DerOps( DerPlugin, Main_Fun): 
    pass
class ConFun( AuxPlugin, CorePlugin, DerPlugin, Main_Fun ):
    pass
# and possible
# class CoreDerOps( CorePlugin, DerPlugin, Main_Fun):
#    pass
# etc. Mix'n'match.

“规则”是:

  1. 插件总是继承自object,除了定义普通方法外不做任何事情。
  2. 在继承基类的类中,插件都位于单个基类的左侧
  3. 插件应该有自己独特的方法集,不与其他兼容插件重叠(但如果重叠,最左边的插件胜出)
  4. 如果你违反了这些规则,你会在以后忘记你的时候后悔,或者其他一些可怜的草皮会诅咒你并破坏你的业力。

您可以在多个层次上重复这种模式:

class FooFun( FooPlugin, ConFun):  
   # gets all of ConFun's plug-in methods, its base class, and added FooPlugin's methods

向下一层,允许使用插件方法拦截和扩充从较低级别继承的方法,在适当的情况下调用super().name()

关键是找出什么是指什么是容易的。如果它在插件中,则无需担心超类。对super() 的任何调用都指向基类,或者更进一步地指向它的继承树。

【讨论】:

  • 那么,“插件”是这个继承工具的非正式名称吗?
  • 是的。它是一种用 Python 编程的方式,而不是语言中内置的任何东西。 “插件”类本身没有用,只有在与基类一起“插入”(继承)时才有用。
  • 太棒了。另外,如果我有一个变量说self.A 在孙类中声明和更新,它是否可以在子类和父类的方法中使用? (我什至没有在常规层次结构中尝试过!)
  • 是的,Python 没有隐藏任何东西,也没有私有变量。 self 指的是实例,所有类/子类代码共享该实例。
猜你喜欢
  • 2018-02-04
  • 2018-01-16
  • 1970-01-01
  • 2012-12-21
  • 2011-08-03
  • 1970-01-01
  • 1970-01-01
  • 2011-07-07
  • 2019-09-13
相关资源
最近更新 更多