http://www.faqs.org/docs/diveintopython/fileinfo_private.html によると:
ほとんどの言語と同様に、Pythonにはプライベート要素の概念があります。
- モジュール外のから呼び出せないプライベート関数
ただし、2つのファイルを定義する場合:
#a.py
__num=1
そして:
#b.py
import a
print a.__num
b.py
を実行すると、1
が例外なしで出力されます。 diveintopythonは間違っていますか、それとも何か誤解しましたか?そして、モジュールの機能をプライベートとして定義するdoする方法はありますか?
Pythonでは、「プライバシー」は「同意する大人の」同意レベルに依存します-あなたはそれをforceすることはできません(実生活でできる以上;-)。単一の先行アンダースコアは、あなたが想定「外部から」アクセスすることではないことを意味します-two先行アンダースコア(後続アンダースコアなし)はメッセージをさらに強力に運びます...しかし、結局のところ、それはまだ社会的慣習とコンセンサスに依存しています:Pythonの内省はあなたが望みを尊重するためにhandcuff他のすべてのプログラマーができないほど強力です。
((ただし、それは密接に保持されている秘密ですが、C++にもほぼ同じです:ほとんどのコンパイラでは、#define private public
ファイルを#include
ingする前の単純な.h
行が、あなたの「プライバシー」のハッシュを作成するのに必要です...! -))
class privatesとmodule privates。
A module private starts with one underscore
このような要素は、from <module_name> import *
形式のインポートコマンドを使用するとコピーされません。ただし、import <moudule_name>
構文を使用する場合はインポートされます( Ben Wilhelmの答えを参照 )
質問の例のa .__ numからアンダースコアを1つ削除するだけで、from a import *
構文を使用してa.pyをインポートするモジュールに表示されなくなります。
A class private starts with two underscores (aka dunder i.e. d-ouble under-score)
そのような変数は、クラス名などを含めるために「マングル」という名前を持っています。
マングルされた名前を介して、クラスロジックの外部からアクセスできます。
名前のマングリングは、不正アクセスに対する軽度の防止デバイスとして機能しますが、その主な目的は、祖先クラスのクラスメンバーとの名前の衝突の可能性を防ぐことです。 Alex Martelliの同意成人に対する面白いが正確な参照を参照してください。これらの変数に関して使用される規則について説明しています。
>>> class Foo(object):
... __bar = 99
... def PrintBar(self):
... print(self.__bar)
...
>>> myFoo = Foo()
>>> myFoo.__bar #direct attempt no go
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute '__bar'
>>> myFoo.PrintBar() # the class itself of course can access it
99
>>> dir(Foo) # yet can see it
['PrintBar', '_Foo__bar', '__class__', '__delattr__', '__dict__', '__doc__', '__
format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__
', '__subclasshook__', '__weakref__']
>>> myFoo._Foo__bar #and get to it by its mangled name ! (but I shouldn't!!!)
99
>>>
モジュールのプライバシーは純粋に慣習的なものではないため、またimportを使用するとモジュールのプライバシーが認識される場合とされない場合があるため、この質問は完全には答えられません。
モジュールでプライベート名を定義する場合、これらの名前willは、 'import module_name'構文を使用するスクリプトにインポートされます。したがって、この例のようにa.pyでプライベートモジュール_numを正しく定義したと仮定します。
#a.py
_num=1
..モジュール名シンボルを使用してb.pyでアクセスできます。
#b.py
import a
...
foo = a._num # 1
A.pyから非プライベートのみをインポートするには、from構文を使用する必要があります。
#b.py
from a import *
...
foo = _num # throws NameError: name '_num' is not defined
ただし、わかりやすくするために、モジュールから名前をインポートするときは、すべてを「*」でインポートするのではなく、明示的にする方が適切です。
#b.py
from a import name1
from a import name2
...
Pythonでは、プライベートのclassが2つの下線プレフィックスを持つメンバーを許可します。この手法はモジュールレベルでは機能しないため、これはDive Into Pythonの間違いだと考えています。
プライベートクラス関数の例を次に示します。
class foo():
def bar(self): pass
def __bar(self): pass
f = foo()
f.bar() # this call succeeds
f.__bar() # this call fails
内部関数を追加できます:
def public(self, args):
def private(self.root, data):
if (self.root != None):
pass #do something with data
そのレベルのプライバシーが本当に必要な場合は、そのようなものが必要です。
これは古くからの質問ですが、モジュールプライベート(アンダースコアが1つ)とクラスプライベート(アンダースコアが2つ)の両方のマングル変数は、標準のドキュメントでカバーされています。
Pythonチュートリアル " クラス " プライベート変数
クロージャーまたは関数を埋め込むことは1つの方法です。これはJSでは一般的ですが、ブラウザ以外のプラットフォームやブラウザワーカーには必要ありません。
Pythonでは少し奇妙に思われますが、何かを本当に隠す必要がある場合は、それが道かもしれません。 python APIを使用して、C(または他の言語)で非表示にする必要があるものを保持することが、おそらく最良の方法です。失敗した場合、コードを関数内に配置し、それを呼び出して、エクスポートするアイテムを返します。