6

Django のソース コードを読んで、この関数を見つけました。ブロックタグの実装です。

私が興味を持っているのは、クラス インスタンスの外側__loaded_blocksから先頭に 2 つのアンダースコア ( ) を持つ変数を設定していることです(パーサーはParser クラスのインスタンスです)。Django ソース コードの簡単な grep は、文字列がここでのみ発生することを示しています。parserloaded_blocks

Python の name-mangling 機能の使用については、これまで考えたことがありませんでしたが、これにより、 の__loaded_blocks属性がparserそれ自体から実質的に隠蔽されます。メソッドからこの属性を読み取るにparserは、 に頼る必要がありますgetattr(self, "__loaded_blocks")

これは、選択した属性名の意図しない未使用の副作用にすぎないと考えるのは正しいですか? それとも、これにはもっと深い目的がありますか?

一般的に、なぜそのようなことをしたいのですか?

編集:__loaded_blocks明確にするために、のメソッドから属性にアクセスしようとしない限り、parser他の属性と同じように機能し、実際にはマングルされた属性ではないことを十分に認識しています。

4

1 に答える 1

3

__インスタンスにプレフィックスが付いたプロパティを追加すると、名前のマングリングは発生しないと思います

ドキュメントから:

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

class Test:
  pass

test = Test()
test.__hello = 'hii'    
test.__hello  # hiii

名前は改ざんされていませんが、コードの利用者には「プライベート」としてマークされています。

于 2012-12-03T14:57:16.367 に答える