使用するためだけのもの(分析)新しいスタイル?
-
13-09-2019 - |
質問
書 Pythonのように(第2版) である
古いスタイルの授業方法を解決クラシックするためだけのものと
どう違うのです。
また例による書き換えの例は、新しいスタイルが、結果は得られた古いスタイル。のpythonのバージョンを使用している実行例 2.5.2. 以下の例:
class Base1(object):
def amethod(self): print "Base1"
class Base2(Base1):
pass
class Base3(object):
def amethod(self): print "Base3"
class Derived(Base2,Base3):
pass
instance = Derived()
instance.amethod()
print Derived.__mro__
通話 instance.amethod()
版画 Base1
, もし私の理解析と新しいスタイルの授業に出力して Base3
.通話 Derived.__mro__
版画
(<class '__main__.Derived'>, <class '__main__.Base2'>, <class '__main__.Base1'>, <class '__main__.Base3'>, <type 'object'>)
いう場合の解析と新しいスタイルの授業内容に誤りがあることをやっていかに間違いれることはできません。力を貸してくださいより良い理解析.
解決
同じ祖先クラスはかつて「ナイーブ」でより多く発生したときに、新しいスタイルのクラス対レガシーのための解決順序との決定的な違いは来る、深さ優先のアプローチ - 例えば、「ダイヤモンド継承」の場合を考えてみます。
>>> class A: x = 'a'
...
>>> class B(A): pass
...
>>> class C(A): x = 'c'
...
>>> class D(B, C): pass
...
>>> D.x
'a'
ここで、レガシー形式、解像度順序はDさ - B - A - C - A:Dxとをルックアップするときに、AはつつC.において定義を隠し、それを解決するために、解像度順に最初の塩基です。
>>> class A(object): x = 'a'
...
>>> class B(A): pass
...
>>> class C(A): x = 'c'
...
>>> class D(B, C): pass
...
>>> D.x
'c'
>>>
ここでは、新しいスタイルは、順序は次のとおりです。
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>,
<class '__main__.A'>, <type 'object'>)
A
がオーバーライド(すなわち、メンバーx
のCさんのオーバーライド)は、実際に分別動作するように、一回だけとそのサブクラスのすべての後の解決順序を入ってくることを余儀なくされている。
これは、古いスタイルのクラスは避けるべきであることを理由の一つです。
他のヒント
Pythonのメソッド解決順序は、実際にはダイヤモンドパターンを理解するよりも複雑です。 のには本当にがそれを理解し、 C3線形化するを見てみましょう。それは本当に順序を追跡するための方法を拡張する際にprint文を使用するのに役立ちます、私を見つけました。たとえば、あなたは、このパターンの出力がどうなるかと思いますか? (注:「X」は2つの交差エッジしないノードであると仮定され、^はsuperを呼び出す方法を意味する())
class G():
def m(self):
print("G")
class F(G):
def m(self):
print("F")
super().m()
class E(G):
def m(self):
print("E")
super().m()
class D(G):
def m(self):
print("D")
super().m()
class C(E):
def m(self):
print("C")
super().m()
class B(D, E, F):
def m(self):
print("B")
super().m()
class A(B, C):
def m(self):
print("A")
super().m()
# A^
# / \
# B^ C^
# /| X
# D^ E^ F^
# \ | /
# G
あなたはB D C E F Gを得たか。
x = A()
x.m()
次のように裁判の多くのエラーの後、私はC3の線形化の非公式グラフ理論の解釈を思い付いた:(誰かこれは間違っているなら、私に知らせてください。)
この例を考えてみます:
class I(G):
def m(self):
print("I")
super().m()
class H():
def m(self):
print("H")
class G(H):
def m(self):
print("G")
super().m()
class F(H):
def m(self):
print("F")
super().m()
class E(H):
def m(self):
print("E")
super().m()
class D(F):
def m(self):
print("D")
super().m()
class C(E, F, G):
def m(self):
print("C")
super().m()
class B():
def m(self):
print("B")
super().m()
class A(B, C, D):
def m(self):
print("A")
super().m()
# Algorithm:
# 1. Build an inheritance graph such that the children point at the parents (you'll have to imagine the arrows are there) and
# keeping the correct left to right order. (I've marked methods that call super with ^)
# A^
# / | \
# / | \
# B^ C^ D^ I^
# / | \ / /
# / | X /
# / |/ \ /
# E^ F^ G^
# \ | /
# \ | /
# H
# (In this example, A is a child of B, so imagine an edge going FROM A TO B)
# 2. Remove all classes that aren't eventually inherited by A
# A^
# / | \
# / | \
# B^ C^ D^
# / | \ /
# / | X
# / |/ \
# E^ F^ G^
# \ | /
# \ | /
# H
# 3. For each level of the graph from bottom to top
# For each node in the level from right to left
# Remove all of the edges coming into the node except for the right-most one
# Remove all of the edges going out of the node except for the left-most one
# Level {H}
#
# A^
# / | \
# / | \
# B^ C^ D^
# / | \ /
# / | X
# / |/ \
# E^ F^ G^
# |
# |
# H
# Level {G F E}
#
# A^
# / | \
# / | \
# B^ C^ D^
# | \ /
# | X
# | | \
# E^F^ G^
# |
# |
# H
# Level {D C B}
#
# A^
# /| \
# / | \
# B^ C^ D^
# | |
# | |
# | |
# E^ F^ G^
# |
# |
# H
# Level {A}
#
# A^
# |
# |
# B^ C^ D^
# | |
# | |
# | |
# E^ F^ G^
# |
# |
# H
# The resolution order can now be determined by reading from top to bottom, left to right. A B C E D F G H
x = A()
x.m()
あなたが得る結果は正しいです。
:Base3
と古典的なクラスのための同じ階層と比較するBase1
の基本クラスを変更してみてください
class Base1(object):
def amethod(self): print "Base1"
class Base2(Base1):
pass
class Base3(Base1):
def amethod(self): print "Base3"
class Derived(Base2,Base3):
pass
instance = Derived()
instance.amethod()
class Base1:
def amethod(self): print "Base1"
class Base2(Base1):
pass
class Base3(Base1):
def amethod(self): print "Base3"
class Derived(Base2,Base3):
pass
instance = Derived()
instance.amethod()
今では出力します:
Base3
Base1
詳細については、この説明を読みます。
いと行動が法の解像度は深さ優先ではな広さがない。Derviedの遺産のように見え
Base2 -> Base1
/
Derived - Base3
なので instance.amethod()
- チェックBase2な見述する.
- 見るBase2してから継承されたBase1のチェックBase1.Base1は
amethod
, なが呼び出されます。
この反映 Derived.__mro__
.単に対して繰り返し処理を実行 Derived.__mro__
停止時までの方法を探索します。