25

このクラスのメソッド内でのみ使用する関数をクラスに追加したいと考えています。これらのメソッドの実装外では呼び出しません。C++ では、クラスのプライベート セクションで宣言されたメソッドを使用します。このような関数を Python で実装する最良の方法は何ですか?

この場合、静的デコレータを使用することを考えています。selfデコレータと単語なしで関数を使用できますか?

4

5 に答える 5

39

Python には、プライベート メソッドや属性の概念がありません。クラスをどのように実装するかがすべてです。ただし、疑似プライベート変数 (名前マングリング) を使用できます。(2 つのアンダースコア) で始まる変数__は、疑似プライベート変数になります。

ドキュメントから:

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

class A:
    def __private(self):
       pass

だから__private今は実際に になり_A__privateます。

静的メソッドの例:

>>> class A:
...     @staticmethod         # Not required in Python 3.x
...     def __private():
...         print 'hello'
...
>>> A._A__private()
hello
于 2013-06-19T14:14:01.313 に答える
8

Python には、他の多くの言語のように「プライベート」という概念がありません。これは、コードのユーザーが責任を持ってコードを使用するという、同意する成人の原則に基づいて構築されています。慣例により、1 つまたは 2 つの先頭のアンダースコアで始まる属性は、内部実装の一部として扱われますが、実際にはユーザーから隠されているわけではありません。ただし、アンダースコアが 2 つあると、属性名の名前マングリングが発生します。

selfまた、言語の機能によるものではなく、慣例によるものであることに注意してください。インスタンス メソッドは、インスタンスのメンバーとして呼び出されると、最初の引数として暗黙的にインスタンスが渡されますが、メソッド自体の実装では、その引数は技術的に任意の名前にすることができます。 selfコードを理解しやすくするための規則にすぎません。その結果、selfメソッドの署名に含めなくても、暗黙的なインスタンス引数が署名内の次の変数名に割り当てられる以外に、実際の機能上の影響はありません。

これはもちろん、クラス オブジェクト自体のインスタンスを暗黙的な最初の引数として受け取るクラス メソッドと、暗黙的な引数をまったく受け取らない静的メソッドでは異なります。

于 2013-06-19T14:13:19.573 に答える
3

Pythonはプライベートを行いません。必要に応じて、慣例に従い、名前の前に単一のアンダースコアを付けることができますが、紳士的な方法でそれを尊重するのは他のコーダー次第です†

†または紳士的

于 2013-06-19T14:14:01.240 に答える
1

あなたはそれをしません:

  • Pythonic の方法は、docstringsを使用してこれらのメソッド/メンバーを文書化せず、「実際の」コード コメントのみを使用することです。規則では、1 つまたは 2 つのアンダースコアを追加します。

  • 次に、メンバーの前に二重アンダースコアを使用できるため、それらはクラスに対してローカルになります (ほとんどの場合、名前マングリングです。つまり、クラス外のメンバーの実際の名前は : になりますinstance.__classname_membername)。継承を使用するときの競合を回避したり、クラスの子の間に「プライベート スペース」を作成したりするのに役立ちます。

  • 私の知る限り、メタクラスを使用して変数を「隠す」ことは可能ですが、それは Python の哲学全体に違反するため、詳細には触れません。

于 2013-06-19T14:13:43.043 に答える