Python は、変数の接頭辞と接尾辞としてアンダースコアを使用して、特別な変数/メソッドを指定します。
主に 4 つの状況があります
1. 1. object # public
2. __object__ # 特別な、Python システムで使用するため、ユーザーはそのように定義すべきではありません
3. __object # private (実行時に名前をマングリングする)
4. _object # 従うPython コーディング規約に従うため、プライベートなものとして考慮してください。
コア スタイル: 変数名の先頭にアンダースコアを使用することは避けてください。
アンダースコアはインタープリタにとって特別な意味を持ち、組み込み識別子で使用される記号であるため、プログラマーは変数名の先頭にアンダースコアを使用しないことをお勧めします。一般に、変数名 _object は「プライベート」とみなされ、モジュールまたはクラスの外部では使用できず、「from moduleimport *」を使用してインポートすることもできません。変数がプライベートである場合、変数を表すために _object を使用することをお勧めします。変数名 __object__ は Python にとって特別な意味を持つため、通常の変数ではこの命名スタイルは避けてください。
Python のプライベートの説明。Python には保護という概念はありません。パブリックかプライベートのどちらかですが、Python のプライベートは C++ や Java とは異なり、名前のマングリング (名前の適応 (その目的は、サブクラスが基本クラスのメソッドまたは属性を誤ってオーバーライドすることを防ぐことです。つまり、プライベートにアクセスするための「単一のアンダースコア」 + クラス名を前に追加することによって (例: _Class__object) メカニズムを追加します。
「単一アンダースコア」で始まるメンバー変数は保護変数と呼ばれます。これは、クラス オブジェクトとサブクラス オブジェクト自体のみがこれらの変数にアクセスできることを意味します。「二重アンダースコア」で始まるメンバー変数は、クラス オブジェクトのみを意味します。それ自体はそれらにアクセスできますが、サブクラス オブジェクトもこのデータにアクセスできません。 (以下に示すように)
単一のアンダースコア (_foo) で始まるものは、直接アクセスできないクラス属性を表しており、クラスが提供するインターフェースを介してアクセスする必要があり、「from xxx import *」で始まるものはインポートできません。二重アンダースコア (__foo) はクラスのプライベート メンバーを表し、二重アンダースコアで開始および終了する (__foo__) は、クラスのコンストラクターを表す __init__() など、Python の特別なメソッド固有の識別を表します。
1.class Foo():
2. def __init__():
4. def public_method():
6. 'これはパブリックメソッドです'
8. . DEF __FULLPRIVATE_METHOD ():
9. 'これは二重アンダースコア リード メソッドです'
11. インスタンス化された FOO のオブジェクト
1. f = Foo()
1. ()ok fullprivate_method()ただし、Python の規則によれば、これらはプライベートとみなされ、外部で使用すべきではありません (これらを使用する必要がある場合、外部で使用しないのが良いプログラミング方法です)。同時に、Python ドキュメントによると、_object と __object の範囲はこのモジュールに限定されています。
=============================================== == ==============================
Python の命名メカニズムを理解する (一重アンダースコアと二重アンダースコアで始まる) (転載: http ://blog.csdn.net/lanphaday)
はじめに
次のプログラムの出力を推測することを皆さんに歓迎します:
class A(object):
def __init__(self):
self.__private()
self. public()
Def __private (self):
Print 'a .__ Private ()'
def Public (SELF):
Print 'A.Public ()'
Class b (a):
def __private (seld):
'B.__ Private ()' を印刷
def public(self):
print 'B.public()'
b = B()
最初の探索
正解は次のとおりです:
A.__private()
B.public()
すでに正しく推測している場合は、推測する必要はありません私のこのブログ投稿を読んでください。推測が正しくなかったり、心に疑問がある場合は、私のこのブログ投稿があなたのためです。
すべては、「A.__private()」が出力される理由から始まります。しかし、その理由を説明するには、Python の命名メカニズムを理解する必要があります。
Pythonのマニュアルによると、変数名(識別子)はPythonのアトミックな要素です。変数名がオブジェクトにバインドされている場合、人間社会と同じように、変数名はオブジェクトを参照しますよね。変数名がコード ブロックに現れる場合、それはローカル変数であり、変数名がモジュールに現れる場合、それはグローバル変数です。モジュールについては誰もがよく理解していると思いますが、コード ブロックは少しわかりにくいかもしれません。ここで説明します:
コード ブロックは、実行可能ユニットとして使用できる Python プログラム テキストの一部であり、モジュール、関数本体、クラス定義はすべてコード ブロックです。それだけでなく、すべての対話型スクリプト コマンドもコード ブロックであり、スクリプト ファイルもコード ブロックであり、コマンド ライン スクリプトもコード ブロックです。
次に、変数の可視性について説明します。スコープの概念を紹介します。スコープとは、コード ブロック内の変数名の可視性です。 ローカル変数がコード ブロックで定義されている場合、スコープにはこのコード ブロックが含まれます。変数が関数コード ブロックで定義されている場合、同じ名前の別の変数がそこで定義されていない限り、スコープは関数ブロック内のすべてのコード ブロックに拡張されます。ただし、クラス内で定義される変数のスコープはクラス コード ブロックに限定され、メソッド コード ブロックには拡張されません。
間違い
前のセクションの理論によれば、コードはクラス A の定義、クラス B の定義、変数 b の定義の 3 つのコード ブロックに分割できます。クラス定義によると、コードではクラス A に 3 つのメンバー変数が定義されていることがわかります (Python の関数もオブジェクトなので、メンバー メソッドがメンバー変数と呼ばれる場合は機能します)。クラス B では 2 つのメンバー変数が定義されています。これは次のコードで確認できます:
>>> print 'n'.join(dir(A))
_A__private
__init__
public
>>> print 'n'.join( B) )
_A__private
_B__private
__init__
public
ねえ、なぜクラス A には _A__private という名前の属性があるのですか?そして__プライベートが消えた!これは Python のプライベート変数の抑制についての話です。
探索
Python に詳しい友人は、Python が 2 つ以上のアンダースコア文字で始まり、2 つ以上のアンダースコア文字で終わらない変数をプライベート変数として扱うことを知っています。プライベート変数は、コード生成前に長い形式に変換されます (公開されます)。変換メカニズムは次のようになります。変数の先頭にクラス名を挿入し、先頭にアンダースコア文字を追加します。これはプライベート名のマングリングと呼ばれます。たとえば、クラス A の __private 識別子は _A__private に変換されます。これが、前のセクションで _A__private と __private が消えた理由です。
さらに 2 つの余談:
まず、ローリングにより識別子が長くなるため、Python はこれによって生じる名前の競合に注意してください。
2 番目に、クラス名がすべてアンダースコアで名付けられている場合、Python はローリングを実行しなくなります。例: & & gt; & gt; & gt; class ____ (オブジェクト):
def __init __ (self):
Print '_____ Method ()' & & GT & ; gt; & gt ; print 'n'.join(dir(____))
__class__
__delattr__
__dict__
__doc__
__getattribute__
__hash__
__init__
__メソッド
__reduce__
__reduce_ex__
__repr__
__setattr__
__str__
__weakref__
>> > obj = ____()
____.__method()
>>> obj.__method() # 戻って理由を見てみましょう Output "A.__private( )」!
真実
賢明な読者ならもう答えを推測していると思いますよね?まだ考えたことがない方にヒントを与えておきます。実際は、C 言語のマクロの前処理に似ています。
クラス A はプライベート メンバー関数 (変数) を定義しているため、コード生成の前にプライベート変数の圧縮が実行されます (前のセクションで赤でマークされた行に注目してください)。ローリング後、クラス A のコードは次のようになります:
class A(object):
DEF __init __ (Self):
Self._a__private () # この行は変更されました
Self.public ()
def _a__private (self): # この行も変更されました
print 'a .__ private () ;
クラスB定義時に__init__メソッドがオーバーライドされていないため、引き続きA.__init__が呼び出され、つまりself._A__private()が実行され、当然「A.__private()」が出力されます。 corde次の2つのコードは、説得力を高め、理解を高めることができます。 .public()'
> ;>> c = C()
C.__private()
C.public()
################### ######
> def __private(self):
public()