Python继承中的方法解析顺序

2021年4月29日18:08:51 发表评论 1,017 次浏览

方法解析顺序:

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

# Python program showing
# how MRO works
  
class 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 works
  
class 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):
     pass
     
r = D()
r.rk()

输出如下:

In class B

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

Python继承中的方法解析顺序1

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: 
     pass
  
  
class B: 
     pass
  
  
class C(A, B): 
     pass
  
  
class D(B, A): 
     pass
  
  
class E(C, D): 
     pass

在上面的示例算法中, 首先查看被调用方法的实例类。如果不存在, 则调查第一个父级, 如果也不存在, 则调查父级的父级。这一直持续到类的深度结束为止, 最后直到继承的类结束。因此, 在我们最后一个示例中, 解析顺序将为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 resolved
  
class 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课程。


木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: