web-dev-qa-db-ja.com

同じクラス内でプライベート関数を呼び出すpython

同じクラス内の他の関数からプライベート関数を呼び出すにはどうすればよいですか?

class Foo:
  def __bar(arg):
    #do something
  def baz(self, arg):
    #want to call __bar

今、私がこれを行うとき:

__bar(val)

baz()から、これを取得します。

NameError: global name '_Foo__createCodeBehind' is not defined

誰かがエラーの理由を教えてもらえますか?また、別のプライベート関数からプライベート関数を呼び出すにはどうすればよいですか?

28
badmaash

C/C++などにあるようなPythonには暗黙のthis->はありません。selfで呼び出す必要があります。

class Foo:
     def __bar(self, arg):
         #do something
     def baz(self, arg):
         self.__bar(arg)

これらのメソッドはreallyプライベートではありません。 2つのアンダースコアでメソッド名を開始すると、Pythonは名前をマングリングして「プライベート」にしますが、それだけです。他の言語とは異なります。 Foo__barを定義しても、Foo._Foo__barを介してオブジェクトの外部からアクセスできます。たとえば、これを行うことができます:

f = Foo()
f._Foo__bar('a')

これは、取得したエラーメッセージの「奇数」識別子についても説明しています。

ドキュメントで here を見つけることができます。

38
Rob Wouters

___bar_は「プライベート」です(名前が mangled であるという意味で)が、それはまだFooのメソッドなので、selfを介して参照し、selfを渡す必要があります。裸の__bar()で呼び出すだけでは機能しません。 self.__bar()のように呼び出す必要があります。そう...

_>>> class Foo(object):
...   def __bar(self, arg):
...     print '__bar called with arg ' + arg
...   def baz(self, arg):
...     self.__bar(arg)
... 
>>> f = Foo()
>>> f.baz('a')
__bar called with arg a
_

Foo定義内のどこからでも_self.__bar_にアクセスできますが、定義の外に出たら、foo_object._Foo__bar()を使用する必要があります。これにより、クラス継承のコンテキストでの名前空間の衝突を回避できます。

それがこの機能を使用している理由でない場合、使用を再検討するかもしれません。 Python)で「プライベート」変数とメソッドを作成するための規則は、名前に アンダースコアを追加 になります。これは構文上の意味はありませんが、変数またはメソッドが変更される可能性のある実装の詳細の一部であるコード。

7
senderle