はPythonにおいては非表示になり、プライベート変数の授業で

StackOverflow https://stackoverflow.com/questions/1641219

  •  08-07-2019
  •  | 
  •  

質問

私のドキュメンテーションシステムの読解とブルース-Eckels' Python3パターン、レシピ、熟語-慣用.

を読みながらいの授業でいPythonではありません必要性を宣言するインスタンス変数.あなただけの使用のコンストラクタ、ブームもあります。

したがって、たとえば、:

class Simple:
    def __init__(self, s):
        print("inside the simple constructor")
        self.s = s

    def show(self):
        print(self.s)

    def showMsg(self, msg):
        print(msg + ':', self.show())

がtrueの場合、そのオブジェクトのクラス Simple できるだけの値を変更する変数 s 外部のクラスです。

例えば:

if __name__ == "__main__":
    x = Simple("constructor argument")
    x.s = "test15" # this changes the value
    x.show()
    x.showMsg("A message")

Javaてまいについて教public/private/protected変数です。そのキーワードの意味がでたい変数クラスでない社外のクラスアクセスできます。

なぜことを要しないPython?

役に立ちましたか?

解決

文化的です。 Pythonでは、他のクラスのインスタンスやクラス変数には書き込みません。 Javaでは、本当にしたい場合に同じことをすることを妨げるものは何もありません-結局、同じ効果を達成するためにクラス自体のソースをいつでも編集できます。 Pythonは、そのような見せかけのセキュリティを廃止し、プログラマーに責任を負わせます。実際には、これは非常にうまく機能します。

何らかの理由でプライベート変数をエミュレートしたい場合は、いつでも__ プレフィックスを使用できます。 0008 / "> PEP 8 。 Pythonは、 __ foo などの変数の名前をマングルし、それらを含むクラスの外部のコードからは簡単に見えないようにします(ただし、 Javaの保護を回避できる のように、十分です。

同じ慣例により、 _ プレフィックスは、技術的に禁止されていない場合でも、近づかないことを意味します。 __ foo _bar のような別のクラスの変数をいじる必要はありません。

他のヒント

Pythonのプライベート変数は多かれ少なかれハックです。インタープリターは意図的に変数の名前を変更します。

class A:
    def __init__(self):
        self.__var = 123
    def printVar(self):
        print self.__var

今、クラス定義の外で __ var にアクセスしようとすると、失敗します:

 >>>x = A()
 >>>x.__var # this will return error: "A has no attribute __var"

 >>>x.printVar() # this gives back 123

しかし、これで簡単に逃げることができます:

 >>>x.__dict__ # this will show everything that is contained in object x
               # which in this case is something like {'_A__var' : 123}

 >>>x._A__var = 456 # you now know the masked name of private variables
 >>>x.printVar() # this gives back 456

OOPのメソッドは次のように呼び出されることをご存知でしょう。 x.printVar()=> A.printVar(x) A.printVar() x の一部のフィールドにアクセスできる場合、このフィールドには外部 A.printVar() ...結局、再利用のために関数が作成されます。内部のステートメントに特別な権限は与えられません。

ゲームは、コンパイラが関与している場合は異なります(プライバシーはコンパイラレベルの概念です)。アクセス制御修飾子を使用したクラス定義について知っているため、コンパイル時にルールが守られていない場合はエラーになる可能性があります

上記のコメントの多くで正しく言及されているように、アクセス修飾子の主な目標を忘れないでください。プライベートフィールドが表示されても、そのフィールドをいじることはありません。そのため、Pythonで_と__を使用して簡単に達成できるのは、ほとんどが構文糖です。

" Javaでは、public / private / protected変数について教えられてきました"

" Pythonで必要ないのはなぜですか?"

同じ理由で、Javaでは必須ではありません。

自由に使用できます- private および protected は使用しません。

PythonおよびJavaプログラマとして、 private および protected は非常に重要な設計概念であることがわかりました。しかし実際問題として、何万行ものJavaとPythonで、 private protected を実際に使用したことはありません。 p>

どうしてですか?

「誰から保護されていますか?」という質問です。

私のチームの他のプログラマー?彼らはソースを持っています。彼らがそれを変更できるとき、保護とはどういう意味ですか?

他のチームの他のプログラマー?彼らは同じ会社で働いています。電話で-ソースを取得できます。

クライアント?それは仕事のためのプログラミングです(一般的に)。クライアントは(通常)コードを所有します。

では、誰が-正確に-私はそれを保護していますか?

アンダースコア規則にはプライベート変数のバリエーションがあります。

In [5]: class Test(object):
   ...:     def __private_method(self):
   ...:         return "Boo"
   ...:     def public_method(self):
   ...:         return self.__private_method()
   ...:     

In [6]: x = Test()

In [7]: x.public_method()
Out[7]: 'Boo'

In [8]: x.__private_method()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-8-fa17ce05d8bc> in <module>()
----> 1 x.__private_method()

AttributeError: 'Test' object has no attribute '__private_method'

いくつかの微妙な違いがありますが、プログラミングパターンのイデオロギーの純粋さのために、それで十分です。

この概念をより厳密に実装する@privateデコレータの例がありますが、YMMVです。おそらく、メタを使用するクラス定義を書くこともできます

Pythonでは、2つのアンダースコアで始まる識別子にクラス名を自動的に付加する機能により、プライベート識別子のサポートが制限されています。ほとんどの場合、これはプログラマには透過的ですが、最終的な効果は、この方法で名前が付けられた変数をプライベート変数として使用できることです。

詳細については、こちらをご覧ください。

一般に、Pythonのオブジェクト指向の実装は、他の言語に比べて少し原始的です。しかし、実際にはこれを楽しんでいます。これは非常に概念的にシンプルな実装であり、言語の動的スタイルによく適合します。

前述のとおり、できることを示す変数やメソッドは、民間によるprefixingでアンダースコア.があった場合には、まずはこのようには上がれます♪※数に限りがございまで使用してください property デコレータ.次に例を示します。

class Foo:

    def __init__(self, bar):
        self._bar = bar

    @property
    def bar(self):
        """Getter for '_bar'."""
        return self._bar

このように、人や物を参照 bar 実際に参照を返却値の型に"byte[]"を指定 bar 機能により、変数自体及びそのためアクセス可能になりますが変更されません。しかし、僕が思うだけで使用 _bar 割り当てる新しい値を代入しています。ありません必ずうまくいく方法を防ぐために変数にアクセス方法をご希望の非表示としてと言われていました。しかし、利用 property は明確なメッセージを送信できる変数ではない編集します。 property にも使用できます複雑になgetter/setter/deleterアクセス経路を説明はこちら https://docs.python.org/3/library/functions.html#property

プライベート変数を使用するのは、変数への書き込みまたは変数からの読み取り時に他のことを行う必要があるときだけです。そのため、セッターやゲッターの使用を強制する必要があります。

繰り返しますが、すでに述べたように、これは文化にも当てはまります。私は、他のクラス変数の読み取りと書き込みがすべて自由に行えるプロジェクトに取り組んできました。ある実装が非推奨になったとき、その関数を使用したすべてのコードパスを識別するのに非常に長い時間がかかりました。セッターとゲッターの使用が強制された場合、非推奨のメソッドが呼び出されたことと、それを呼び出すコードパスを識別するデバッグステートメントを簡単に記述できます。

誰でも拡張機能を作成できるプロジェクトにいる場合、いくつかのリリースで廃止される非推奨のメソッドをユーザーに通知することは、アップグレード時にモジュールの破損を最小限に抑えるために不可欠です。

だから私の答えは;あなたとあなたの同僚が単純なコードセットを維持している場合、クラス変数を保護することは必ずしも必要ではありません。拡張可能なシステムを作成している場合、コードを使用するすべての拡張機能でキャッチする必要があるコアへの変更が行われると、それが不可欠になります。

プライベートおよび保護された概念は非常に重要です。しかし、Python-制限されたリソースを開発に使用できるプロトタイピングと迅速な開発のためのツールです。そのため、Pythonでは保護レベルの一部がそれほど厳しくありません。 &quot; __&quot;を使用できます。クラスメンバでは、適切に動作しますが、十分に見えません-そのようなフィールドへの各アクセスには、これらの文字が含まれています。

また、Python OOPの概念は完全ではなく、smaltalkまたはrubyは純粋なOOPの概念にはるかに近いことがわかります。 C#またはJavaでさえも近いです。

Pythonは非常に優れたツールです。しかし、それは単純化されたOOP言語です。構文的および概念的に簡素化されました。 pythonの存在の主な目標は、非常に高速な方法で、高い抽象化レベルで読みやすいコードを開発者が作成できるようにすることです。

「復活」についてはごめんなさい。スレッド、しかし、これが誰かを助けることを願っています:

Python3では、単に「カプセル化」したい場合Javaのようなクラス属性では、次のように同じことができます。

class Simple:
    def __init__(self, str):
        print("inside the simple constructor")
        self.__s = str

    def show(self):
        print(self.__s)

    def showMsg(self, msg):
        print(msg + ':', self.show())

これをインスタンス化するには:

ss = Simple("lol")
ss.show()

注意: print(ss .__ s)はエラーをスローします。

実際には、Python3はグローバル属性名を難読化します。これを「プライベート」に変えるJavaのような属性。属性の名前はまだグローバルですが、他の言語のプライベート属性のように、アクセスできない方法です。

しかし、恐れることはありません。関係ありません。それも仕事をします。 ;)

Pythonには、C ++やJavaのようなプライベート変数はありません。必要に応じて、いつでも任意のメンバー変数にアクセスできます。ただし、Pythonでクラス変数を公開するのは悪くないため、Pythonでプライベート変数は必要ありません。メンバー変数をカプセル化する必要がある場合は、&quot; @ property&quot;を使用してこれを行うことができます。後で既存のクライアントコードを壊すことなく。

Pythonでは、単一のアンダースコア&quot; _&quot;メソッドまたは変数がクラスのパブリックAPIの一部と見なされないこと、およびAPIのこの部分が異なるバージョン間で変更される可能性があることを示すために使用されます。これらのメソッド/変数を使用できますが、このクラスの新しいバージョンを使用すると、コードが破損する可能性があります。

二重アンダースコア&quot; __&quot; 「プライベート変数」を意味するものではありません。これを使用して、「クラスローカル」変数を定義します。そして、サブクラスによって簡単にオーバーライドすることはできません。変数名をマングルします。

例:

class A(object):
    def __init__(self):
        self.__foobar = None # will be automatically mangled to self._A__foobar

class B(A):
    def __init__(self):
        self.__foobar = 1 # will be automatically mangled to self._B__foobar

self .__ foobarの名前は、クラスAのself._A__foobarに自動的にマングルされます。クラスBでは、self._B__foobarにマングルされます。したがって、すべてのサブクラスは、その親変数をオーバーライドすることなく、独自の変数__foobarを定義できます。しかし、二重アンダースコアで始まる変数にアクセスすることを妨げるものは何もありません。ただし、名前のマングリングにより、この変数/メソッドを偶発的に呼び出すことはできません。

レイモンド・ヘッティンガーズが「Pythonクラス開発ツールキット」と話すことを強くお勧めします。 Pycon 2013(Youtubeで入手可能)から、@ propertyおよび&quot; __&quot; -instance変数を使用する理由と方法の良い例を示します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top