2

次のコード:

class MyClass():
    def test(self):
        self.__x = 0

    def __setattr__(self, name, value):
        print name

    def __getattr__(self, name):
        print name
        raise AttributeError(name)

x = MyClass()
x.test()
x.__y

出力:

_MyClass__x
__y
Traceback (most recent call last):
...
AttributeError: __y

「名前」が「属性の名前」であると記載されているドキュメントはまったく役に立ちませんが、何らかの理由で、設定するか取得するかによって異なります。

私が知りたいのは:

  • 私はここで根本的に間違ったことをしていますか?
  • x代わりに最初のケースを取得するにはどうすればよい_MyClass__xですか?
4

2 に答える 2

5

二重アンダースコアは、名前マングリングを呼び出します。名前マングリングが必要ない場合は、doubleundescoreを使用しないでください

オブジェクト名の前のシングルアンダースコアとダブルアンダースコアの意味は何ですか?

Pythonドキュメントから

9.6。プライベート変数

オブジェクト内以外からアクセスできない「プライベート」インスタンス変数は、Pythonには存在しません。ただし、ほとんどのPythonコードには規則があります。アンダースコア(たとえば)が前に付いた名前_spamは、APIの非公開部分(関数、メソッド、またはデータメンバー)として扱われる必要があります。これは実装の詳細と見なされ、予告なしに変更される場合があります。

クラスプライベートメンバーには有効なユースケースがあるため(つまり、サブクラスによって定義された名前と名前の名前の衝突を回避するため)、名前マングリングと呼ばれるこのようなメカニズムのサポートは制限されています。フォームの識別子__spam(少なくとも2つの先頭のアンダースコア、最大で1つの末尾のアンダースコア)は、テキストで。に置き換えられます_classname__spam。ここで、classnameは、先頭のアンダースコアが削除された現在のクラス名です。このマングリングは、クラスの定義内で発生する限り、識別子の構文上の位置に関係なく実行されます。

マングリングルールは主に事故を避けるために設計されていることに注意してください。プライベートと見なされる変数にアクセスしたり、変更したりすることは引き続き可能です。これは、デバッガーなどの特別な状況でも役立ちます。

に渡されたコードexeceval()またはexecfile()呼び出し元のクラスのクラス名が現在のクラスであると見なされないことに注意してください。これはグローバルステートメントの効果に似ており、その効果は同様に一緒にバイトコンパイルされるコードに制限されます。同じ制限が、、、、および直接参照する場合にも適用されますgetattr()setattr()delattr()__dict__

于 2010-03-05T11:52:46.483 に答える
1

なぜこれが発生するのか正確にはわかりませんが、期待どおりに機能するの_xではなく、使用する場合。__x

于 2010-03-05T11:55:33.337 に答える