Python继承中的方法解析顺序

方法解析顺序:
方法解析顺序(MRO), 它表示编程语言解析方法或属性的方式。 Python支持从其他类继承的类。被继承的类称为父类或超类, 而被继承的类称为子级或子类。在python中, 方法解析顺序定义了执行方法时搜索基类的顺序。首先, 在类中搜索方法或属性, 然后遵循我们在继承时指定的顺序。此顺序也称为一类的线性化, 规则集称为MRO(方法解析顺序)。从另一个类继承时, 解释器需要一种方法来解析通过实例调用的方法。因此, 我们需要方法解析顺序。例如

# Python program showing # how MRO worksclass A: def rk( self ): print ( " In class A" ) class B(A): def rk( self ): print ( " In class B" )r = B() r.rk()

输出如下:
In class B

在上面的示例中, 调用的方法来自类B, 但不是来自类A, 这是由于方法解析顺序(MRO)引起的。
上面的代码中遵循的顺序是-
class B-> class A
在多重继承中, 方法是在继承类时根据指定的顺序执行的。对于支持单继承的语言, 方法解析顺序并不重要, 但是支持多继承方法解析顺序的语言起着至关重要的作用。让我们来看另一个示例, 以深入了解方法解析顺序:
# Python program showing # how MRO worksclass A: def rk( self ): print ( " In class A" ) class B(A): def rk( self ): print ( " In class B" ) class C(A): def rk( self ): print ( "In class C" )# classes ordering class D(B, C): passr = D() r.rk()

输出如下:
In class B

在上面的例子中,我们使用了多重继承,它也被称为钻石继承或死亡钻石,它看起来如下:
Python继承中的方法解析顺序

文章图片
Python遵循深度优先查找顺序, 因此最终从类A调用该方法。通过遵循方法解析顺序, 查找顺序如下。
Class D-> Class B-> Class C-> Class A
Python遵循深度优先的顺序来解析方法和属性。因此, 在上面的示例中, 它执行了类B中的方法。
新旧样式顺序:
在旧版本的Python(2.1)中, 我们必须使用旧式类, 而在Python(3.x和2.2)中, 我们必须仅使用新类。新样式类是其第一个父类继承自Python根" object"类的类。
# Old style class class OldStyleClass: pass# New style class class NewStyleClass( object ): pass

两种声明风格中的方法解析顺序(MRO)是不同的。旧样式类使用DLR或深度优先从左到右的算法,而新样式类使用C3线性化算法进行方法解析,同时进行多个继承。
DLR算法
在实现多重继承的过程中, Python建立了一个要搜索的类的列表, 因为它需要解析实例调用某个方法时必须调用的方法。顾名思义, 方法解析顺序将先搜索深度, 然后从左到右。例如
class A: passclass B: passclass C(A, B): passclass D(B, A): passclass E(C, D): pass

【Python继承中的方法解析顺序】在上面的示例算法中, 首先查看被调用方法的实例类。如果不存在, 则调查第一个父级, 如果也不存在, 则调查父级的父级。这一直持续到类的深度结束为止, 最后直到继承的类结束。因此, 在我们最后一个示例中, 解析顺序将为D, B, A, C, A。但是, A不能两次出现, 因此顺序将为D, B, A, C。但是该算法以不同的方式变化, 并且因此, Samuele Pedroni首先发现了一个不一致之处, 并引入了C3线性化算法。
C3线性化算法:
C3线性化算法是一种使用新型类的算法。它用于消除DLR算法产生的不一致。它具有一定的局限性:
  • 孩子先于父母
  • 如果一个类继承自多个类, 则它们将按照基类的元组中指定的顺序保留。
C3线性化算法遵循以下三个规则:
  • 继承图确定方法解析顺序的结构。
  • 用户只有在访问了本地类的方法之后才必须访问超类。
  • 单调性
类的方法解析顺序(MRO)的方法:
要获得类的方法解析顺序,我们可以使用__mro__属性或mro()方法。通过使用这些方法,我们可以显示方法解析的顺序。例如
# Python program to show the order # in which methods are resolvedclass A: def rk( self ): print ( " In class A" ) class B: def rk( self ): print ( " In class B" )# classes ordering class C(A, B): def __init__( self ): print ( "Constructor C" )r = C()# it prints the lookup order print (C.__mro__) print (C.mro())

输出如下:
Constructor C (< class '__main__.C'> , < class '__main__.A'> , < class '__main__.B'> , < class 'object'> ) [< class '__main__.C'> , < class '__main__.A'> , < class '__main__.B'> , < class 'object'> ]

首先, 你的面试准备可通过以下方式增强你的数据结构概念:Python DS课程。

    推荐阅读