龙空技术网

Python方法解析顺序教程

杨同学编程 159

前言:

而今你们对“python顺序函数”大体比较关怀,咱们都需要剖析一些“python顺序函数”的相关文章。那么小编同时在网络上网罗了一些关于“python顺序函数””的相关内容,希望兄弟们能喜欢,咱们一起来学习一下吧!

理解 Python 解析函数的方式和顺序很重要。您需要知道您的代码将在何处调用,何时调用它,一旦您开始使用多个其他类继承的类,事情就会变得混乱。

在本教程中,我们将研究 Python 3 如何MRO通过使用一个叫做C3 Linearization.

继承的问题

想象一下,您正在实现一种具有继承特性的编程语言。当您第一次接近这个主题时,您决定:一个子类将拥有它的父类应该拥有的所有功能和属性!

现在这可能适用于绝大多数场景,但是如果两个父类都实现了相同的功能或属性会发生什么?你如何决定哪个函数或属性优先?

这被称为钻石问题。某些语言(例如 Scala)使用一种称为right-first depth-first search解决此问题的算法。Python 3 使用C3 linearization algorithm.

一个实际例子

让我们通过一个非常简单的方法 Python 程序来看看Method Resolution Orderor是如何MRO实际工作的。我们将定义两个不继承任何内容的类,第三个类同时继承两者。

其特别之处在于我们的my_super_class类继承的两个类都定义了一个test_func(self)函数。

当我们运行这段代码时会发生什么?

class awesome_class():    def __init__(self):        print("My Awesome Class")    def test_func(self):        print("This is my awesome class")class not_so_awesome_class():    def __init__(self):        print("My Not So Awesome Class")    def test_func(self):        print("This is my not so awesome class")class my_super_class(awesome_class, not_so_awesome_class):    def __init__(self):        print("My Super Class")my_class = my_super_class()my_class.test_func()
输出

When we run the above code you should see that the __init__ function is called of our my_super_class class. It then calls the inherited test_func(self) function from the its inherited awesome_class.

 $ python3.6 test.pyMy Super ClassThis is my awesome class

If we were to switch the order in which our my_super_class inherits then you’ll see that the test_func() from the not_so_awesome_class is called instead. Key takeaway from this point is that ordering of inheritance matters.

C3 Linearization

Let’s now have a look at this C3 superclass linearization algorithm and how it works. We can define it as so:

The C3 Superclass Linearization of a class is the sum of the class plus a unique merge of the linearizations of its parents and a list of the parents itself.

This may not mean a lot to most people, so let’s try and demystify what all this means by breaking it down.

C3 does the following:

It guarantees that base class declaration is preservedIt guarantees that subclasses appear before base classesIt guarantees that for every class in a graph of all inherited classes, they adhere to the previous two pointsAn Example

Let’s have a look at the following class inheritance graph from the algo’s wiki:

Basically in this graph class O does not have any parents and features a number of children: [A, B, C, D, E]. Our [A, B, C] classes are the parents to K1, [D, B, E] for K2 and [D, A] for K3. Finally class Z extends from [K1, K2, K3].

This represents a fairly complex dependency graph and not typically representative of “normal” systems, however it gives us lots of examples to dissect how C3 works.

Let’s start breaking this down:

Class

Linearization

Comments

L(O)

[0]

This is relatively trivial and would be [0] as it has no parents

L(A)

[A] + merge(l[O], [O])

The linearization of A is A plus the merge of its parent’s,

[A, O]

Thus the final linearization equals [A,O]

L(B)

[B, O]

[B, C, D, E] all have very similar linearizations

L(K1)

[K1] + merge(L(A), L(B), L(C), [A,B,C])

First we need to find the linearizations of K1’s parents, [A, B, C] and merge them with the parent list [A, B, C]

[K1] + merge([A,O], [B,O, [C,O], [A,B,C]])

Class A is a good candidate as it is the head of the parent list

[K1, A] + merge([O], [B, O], [C, O], [B, C])

We shouldn’t choose class O here as it appears in the tails of list 2 and 3, the next suitable class is B

[K1, A, B] + merge([O], [O], [C,O], [C])

Again O is not a good candidate, we now go with C

[K1, A, B, C] + merge([O], [O], [O])

最后我们必须选择 O 类,因为所有其他选项都用尽了

[K1、A、B、C、O]

我们的最终解决方案

练习:L(Z)根据上面的例子计算出 的线性化。

结论

希望这篇文章Method Resolution Order能让您更深入地了解 Python 3 的工作原理。如果您觉得这很有用或需要进一步的帮助,请在下面的评论部分告诉我。

标签: #python顺序函数