7

私はこの振る舞い(Python 3.2を使用)に少し混乱しています:

class Bar:
    pass

bar = Bar()
bar.__cache = None
print(vars(bar))        # {'__cache': None}

class Foo:
    def __init__(self):
        self.__cache = None

foo = Foo()
print(vars(foo))        # {'_Foo__cache': None}

二重アンダースコアによって属性名が「マングル」される方法について少し読んだことがありますが、上記の両方の場合で同じ名前マングリングを期待していました。

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

ここで何が起こっているのかアイデアはありますか?

4

2 に答える 2

12

名前のマングリングは、classステートメントの評価中に発生します。の場合Bar__cache属性はクラスの一部として定義されるのではなく、事後に特定のオブジェクトに追加されます。

(実際には、完全に正しくない場合があります。__new__メソッドの評価中に名前マングリングが発生する可能性があります。わかりません。ただし__cache、クラスコードではなく、単一のオブジェクトに明示的に追加されます。)

于 2012-11-21T16:57:35.433 に答える
9

ドキュメントから

プライベート名のマングリング:クラス定義でテキストで使用される識別子が2つ以上のアンダースコア文字で始まり、2つ以上のアンダースコアで終わらない場合、そのクラスのプライベート名と見なされます。プライベート名は、コードが生成される前に、より長い形式に変換されます。トランスフォーメーションは、名前の前にクラス名を挿入し、先頭の下線を削除し、クラス名の前に1つの下線を挿入します。たとえば、__spamHamという名前のクラスで発生する識別子は次のように変換されます。_Ham__spam。この変換は、識別子が使用される構文コンテキストとは無関係です。変換された名前が非常に長い場合(255文字より長い場合)、実装で定義された切り捨てが発生する可能性があります。クラス名がアンダースコアのみで構成されている場合、変換は行われません。

クラスが定義された後にプロパティを割り当てています

于 2012-11-21T16:56:24.193 に答える