2

Python の本当に優れた点の 1 つは、アクセサーと同じ名前の変数に名前を付けることができる単純さです。

self.__value = 1

def value():
    return self.__value

サブクラス化したいクラスのプライベート メンバーへのアクセスを提供する簡単な方法はありますか? アクセサーやミューテーターを常に使用せずに、クラス内の生データ オブジェクトを単純に操作したいことがよくあります。

これがプライベートとパブリックの一般的な考え方に反しているように見えることはわかっていますが、通常、サブクラス化しようとしているクラスは私自身のものであり、メンバーをサブクラスに公開することは非常に満足していますが、そのクラスのインスタンスには公開しません. この区別を明確にする方法はありますか?

4

3 に答える 3

5

カプセル化をさらに壊すことなく、便利ではありません。二重下線属性は、アクセスされているクラスの先頭に「_ClassName」を追加することによって名前がマングルされます。したがって、「__value」属性を持つ「ContainerThing」クラスがある場合、属性は実際には「_ContainerThing__value」として格納されます。 . クラス名の変更 (または属性が割り当てられている場所のリファクタリング) は、その属性にアクセスしようとするすべてのサブクラスを壊すことを意味します。

これがまさに、二重下線による名前マングリング (これは実際には「プライベート」ではなく、「不便」なだけです) を使用するのが悪い考えである理由です。先頭のアンダースコアを1 つだけ使用してください。あなたの 'private' 属性に触れてはいけないことは誰もが知っているでしょうし、サブクラスやその他の非常に便利な状況でアクセスすることもできます。二重下線属性の名前マングリングは、特定のクラスに本当に固有の属性の名前の衝突を避けるためにのみ役立ちますが、これは非常にまれです。名前マングルされた属性でさえ簡単にアクセスできるため、追加の「セキュリティ」は提供されません。

なお、' __value' と ' value' (および ' _value') は同じ名前ではありません。アンダースコアは名前の一部です。

于 2008-10-02T15:06:26.490 に答える
3

「これはプライベートとパブリックの一般的な考え方に反しているように見えることはわかっています」実際には「反対」ではなく、C++やJavaとは異なるだけです。

プライベート -- C++ および Java で実装されているように、あまり有用な概念ではありません。実装の詳細を分離すると役立つ場合があります。しかし、それは使いすぎです。

2 で始まる Python の名前__は特別であり、通常、このような名前で属性を定義するべきではありません。を含む名前__は特別で、実装の一部です。そしてあなたの使用のために公開されます。

1 で始まる名前_は「プライベート」です。時々、それらは少し隠されています。ほとんどの場合、「同意する大人」の規則が適用されます。愚かに使用しないでください。通知なしに変更される可能性があります。

"private" は引用符で囲みます。これは、あなたとユーザーとの間の単なる合意に過ぎないからです。でマークを付けました_。ユーザー (およびあなた自身) はそれを尊重する必要があります。

多くの場合、メソッド関数名には、_それらが「プライベート」であり、予告なしに変更される可能性があると見なされていることを示す先頭の付いたものがあります。

Java が必要とする無限のゲッターとセッターは、Python ではあまり使用されていません。Python のイントロスペクションはより柔軟で、オブジェクトの属性値の内部ディクショナリにアクセスでき、 や などのファースト クラスの関数がありgetattr()ますsetattr()

さらに、property()ゲッターとセッターを単純な属性のように振る舞う単一の名前にバインドするためによく使用される関数がありますが、実際には明確に定義されたメソッド関数呼び出しです。

于 2008-10-02T21:28:20.113 に答える
1

どこから引用すればよいかわかりませんが、アクセス保護に関する次の声明は Pythonic の正典です。

Thomas Wouters が述べたように、単一の先頭のアンダースコアは、属性をオブジェクトの内部状態の一部としてマークする慣用的な方法です。2 つのアンダースコアは、属性への簡単なアクセスを防ぐために名前のマングリングを提供するだけです。

その後、ライブラリのクライアントが「プライベート」属性に干渉して自分の足を撃ったりしないことを期待する必要があります。

于 2008-10-02T17:32:12.910 に答える