これは "Effective Python"の例です。私は自分自身を説得するためにいくつかのプリントを追加しましたが、私はまだ不明です。pythonのプライベート属性名mangling継承
継承されたプライベート変数にアクセスしようとすると、子のインスタンス辞書で名前が変更されているため、失敗します(最後の行はa.__value
にアクセスしようとすると正しく失敗します。 mangled版_ApiClass__value
)。
ここで、私が問題になっているのは、継承されたメソッドget
にこの問題がない理由です。 get
への呼び出しでself.__dict__
を印刷すると、子から直接ドット区切りのアクセスを使用しようとしたときと同じChildインスタンスdictを使用していることがわかります。このメソッド内からのドット付き属性アクセスは、何らかの形で適切に変換された名前に変換され、プライベート変数を取得します。
アトリビュートアクセスについての私の理解は、カバーの下で、基本的に起こっていることは(簡略化していますが)a.__value
は基本的にa.__dict__['__value']
です。これは理にかなっており、継承されたプライベート変数に直接アクセスしようとすると証明されます。しかし、継承されたメソッドget
は、同じインスタンスでChildから操作されていますが、ドット付きのアクセスで動作するため、明らかにa.__dict__['__value']
ではなく、a.__dict__['_ApiClass__value']
です。
get
メソッド内のプライベート属性へのアクセスで、子からの同様の属性アクセスではなく、変更された名前が認識されるのは何ですか?
class ApiClass():
def __init__(self):
self.__value = 5
def get(self):
print(self.__dict__['_ApiClass__value']) #succeeds
print(self.__dict['__value']) #fails bc name mangle
return self.__value #how is this translated to '_ApiClass_value'
#but a similar instance lookup fails?
class Child(ApiClass):
def __init__(self):
super().__init__()
self._value = 'hello'
a = Child()
print(a.__dict__)
print(a.get()) #works, but instance dict has no '__value' key?
print(a.__value) #fail bc name mangled to '_ApiClass_value'
'ApiClass.get()'の2行目のコメントは、その行がうまくいかないことを示唆していますが、それは問題ありません。 'a .__ value'にアクセスしようとする最後の行を除いて、エラーなしでこのコードを実行できます。 – Craig
manglingルールについては、ドキュメントで明確に説明しています。https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references – Craig
@Craig - 2番目の誤字を修正しましたライン、それについて申し訳ありません。それは、私にドキュメントを紹介することは特に役に立たないと言いました。 – Solaxun