0

Python で NVI (非仮想インターフェイス) イディオムを試していたところ、プライベート (二重アンダースコア) メソッドが仮想として機能していないように見えることに気付きました。

class A(object):
    def a(self):
        print "in A.a"
    self.b()
    self.__b()
    self._b()

def _b(self):
    print "in A._b"

def __b(self):
    print "in A.__b"

def b(self):
    print "in A.b"

class B(A):
def __b(self):
    print "in B.__b"

def b(self):
    print "in B.b"

def _b(self):
    print "in B._b"

>>> a=A()
>>> b=B()
>>> a.a()
in A.a
in A.b
in A.__b
in A._b
>>> b.a()
in A.a
in B.b
in A.__b
in B._b

これは、二重下線メソッドの名前マングリングが原因である可能性があると推測していますが、直感に反しています。さらに、Python のドキュメント「(C++ プログラマー向け: Python のすべてのメソッドは事実上仮想です。)」から混乱が生じます。

4

2 に答える 2

1

あなたの分析は正しいです。これは名前のマングリングによるもので、事実上A.__b無関係になりB.__bます (マングルされた名前が異なるため)。

于 2013-01-30T19:14:34.140 に答える
1

ドキュメントにあるように、二重先頭アンダースコア メソッドはclass-private members用です。それらは、そのクラス継承サブツリーではなく、それらが使用される特定のクラスに対してプライベートです。それがポイントです。これらは、サブクラス定義で値をオーバーライドしたり、サブクラス メソッドにアクセスしたりしたくないクラス固有の変数用に設計されています。

名前マングリングがあなたが説明する動作の原因であることは正しいです。すべての Python メソッドは、オーバーライドできるという点で実際に仮想です。二重下線メソッドは、名前をマングリングすることで、クラス外からのアクセスを困難にするだけです。classA.__bでメソッドを定義することでオーバーライドできます。そもそも二重アンダースコアを使用する目的を覆すことになるため、それは悪い考えですが、可能です。_A__bB

于 2013-01-30T19:18:47.413 に答える