-4

与えられた

class A:
    x = 'Ac'
    def f(self):
        return self.x

class B(A):
    x = 'Bc'
    def f(self):
        return self.x

class C(A):
    x = 'Cc'
    def f(self):
        return self.x

class D(B, C):
    x = 'Dc'
    def __init__(self):
        self.x = 'Di'
    def f(self):
        return self.x

d = D()
  1. 名前解決の順序はd.x何ですか?例えばDi, Dc, Bc, Cc, Ac

  2. 名前解決の順序はsuper(D, d).x何ですか?

  3. のnroは何self.xですかsuper(D, d).f()?と同じd.f()ですか?

  4. nroは何D.xですか?

  5. 私が割り当ててそこd.xDiいなかった場合、それはどこに行きますか?例DiまたはDc

  6. 私が割り当ててそこD.xDcいなかった場合、それはどこに行きますか?

  7. 私が割り当ててそこsuper(D, d).xBcいなかった場合、それはどこに行きますか?例DiまたはDcまたはBc

4

2 に答える 2

3

オブジェクトが新しいスタイルのオブジェクト(から継承)の場合は、属性またはメソッドをobject使用してメソッドの解決順序を出力し、回答を取得できます。__mro__mro

クラスAを次のように変更します。

class A(object):
    ...

次に、各クラスのメソッド解決順序を印刷できます。

>>> A.__mro__
(<class 'junk.A'>, <type 'object'>)
>>> B.__mro__
(<class 'junk.B'>, <class 'junk.A'>, <type 'object'>)
>>> C.__mro__
(<class 'junk.C'>, <class 'junk.A'>, <type 'object'>)
>>> D.__mro__
(<class 'junk.D'>, <class 'junk.B'>, <class 'junk.C'>, <class 'junk.A'>, <type 'object'>)

新しいスタイルのPythonクラスのstackoverflowの質問メソッド解決順序(MRO)には、いくつかの有用な情報があります。

于 2012-09-20T20:32:09.600 に答える
2

まず、どこでもNoneではなく、各ポイントで異なる値を割り当てると、作業が非常に簡単になります。しかし、私はあなたの質問に尋ねられたように答えようとします。

最初に注意することは、dインスタンスには実際にxは4つではなく1つのコピーしかないということです。これは非常に簡単にテストできます。

>>> d.x = 3
>>> B.f(d)
3

C ++のような言語では、Dには個別のB :: x、C :: x、およびD :: xデータメンバーがあるため、出力はNoneになります。(ここでは、Aが存在しないふりをしています。これは、議論がはるかに複雑になり、実際には質問とは関係がないためです。)

または、さらに簡単に:

>>> dir(d)
['__doc__', '__init__', '__module__', 'f', 'x']

そこにいるのはそれだけです。同じself.xに4回割り当てました。

一方、クラスにはそれぞれ独自のコピーがあります。インスタンス変数がない場合、これらはmroと同じ順序で検索されます。これも簡単にテストできます。

>>> del d.x
>>> B.x = 4
>>> C.x = 5
>>> D.x = 6
>>> d.f()
6
>>> C.f(d)
6
>>> del D.x
>>> d.f()
4

設定に関しては、それは簡単です。設定d.xは常にインスタンス変数を設定するか(4つではなく1つしかないことを忘れないでください)、存在しない場合は作成します。一方、そのクラスのクラス変数を設定D.xまたは設定または作成します。B.xしたがって、継承階層は関係ありません。

于 2012-09-20T21:18:32.607 に答える