1. ホーム
  2. python

[解決済み] 変数とメソッドでのアンダースコアとダブルアンダースコア [重複]

2022-05-17 04:52:04

質問

誰かが私に__method()が混乱することを説明するのに十分親切でしたが、助けを必要とする他の多くの人々がいるので、彼をさらに悩ませる代わりに、私は誰かがさらに違いを詳しく説明することができるかどうか疑問に思っていました。

例えば、私はマングリングを必要としませんが、誰かがinstance._method()を行うことができないように、_はプライベートのままなのでしょうか?それとも、ユニークにすることで、他の変数を上書きしないようにするだけでしょうか? 私は内部メソッドを隠す必要はありませんが、それらは使用するために特定されているので、クラスの外側で使用されることを望みません。

どのように解決するのですか?

から PEP 8 :

  • _single_leading_underscore : 弱い内部使用のインジケータです。 例

    from M import *

    はアンダースコアで始まる名前のオブジェクトをインポートしません。

  • single_trailing_underscore_ : Pythonのキーワードとの衝突を避けるため、慣習的に使用されています。

    Tkinter.Toplevel(master, class_='ClassName')

  • __double_leading_underscore : クラスの属性に名前を付けるとき、名前変換を行います。 を呼び出す (クラス内 FooBar , __boo になる _FooBar__boo になります。)

  • __double_leading_and_trailing_underscore__ : マジックオブジェクトやアトリビュート。 属性です。 例 __init__ , __import__ または __file__ . このような名前は決して作らないでください。 を使用してください。

また、David Goodger の Pythonistaのようなコード :

属性 interface , _internal , __private

しかし、なるべく __private の形式は避けるようにしてください。私は絶対に使いません。私を信じてください。もし を使うと、後で後悔することになります。

説明します。

C++ や Java のバックグラウンドを持っている人は、特にこの機能を使いすぎたり、誤用したりしがちです。 この機能を過剰に使用したり、誤って使用したりします。しかし __private という名前は、JavaやC++と同じようには機能しません。 JavaやC++と同じようにはいきません。それらは、サブクラスでの偶発的な名前空間の衝突を防ぐために、名前のマングリングを その目的は、サブクラスでの偶発的な名前空間の衝突を防ぐことです。 MyClass.__private は単に MyClass._MyClass__private . (ただし と同じ名前を持つサブクラスでは、これでも破綻してしまうことに注意してください。 スーパークラスと同じ名前を持つサブクラス、例えば異なるモジュールのサブクラスでは、これが破綻することに注意してください)。へのアクセスは可能です。 アクセス __private の名前にアクセスすることは可能ですが、不便で壊れやすいだけです。 壊れやすい(スーパークラスの正確な名前への依存が追加される)だけです。

問題は、クラスの作成者が合法的に "この 属性/メソッド名はプライベートであるべきで、このクラス定義の中からしかアクセスできません。 このクラス定義の中からのみアクセス可能であるべきだ。 __private を使用することです。しかし、後で そのクラスのユーザは、その名前へのアクセスを合法的に必要とするサブクラスを作成することができます。 にアクセスする必要があります。そのため、スーパークラスを修正する必要があります。 (を変更しなければならないか、サブクラスのコードが は手動でマングルした名前を使用しなければなりません (これは醜くて壊れやすい)。

Pythonには、quot;we're all consenting adults here"というコンセプトがあります。もし を使用する場合 __private を使う場合、あなたは誰からその属性を守っているのでしょうか? スーパークラスの属性を適切に使用するのはサブクラスの責任です。 また、スーパークラスはその属性を適切に文書化する責任があります。 スーパークラスはその属性を適切に文書化する責任があります。

シングルリーディング・アンダースコアの規約を使うのがよいでしょう。 _internal これは名前が混乱しているわけではありません。 これは内部的な実装の詳細であるため、注意する必要があります。 完全に理解していないのであれば、触れないでください。これは単なる 規約でしかないのですが。