前言:
而今你们对“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顺序函数