web-dev-qa-db-fra.com

Appel d'une fonction privée dans la même classe python

Comment puis-je appeler une fonction privée à partir d'une autre fonction de la même classe?

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

En ce moment, quand je fais ça:

__bar(val)

de baz (), je reçois ceci:

NameError: global name '_Foo__createCodeBehind' is not defined

Quelqu'un peut-il me dire quelle est la raison de l'erreur? De plus, comment puis-je appeler une fonction privée à partir d'une autre fonction privée?

28
badmaash

Il n'y a pas de this-> in Python comme vous l'avez en C/C++ etc. Vous devez l'appeler sur self.

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

Cependant, ces méthodes ne sont pas vraiment privées. Lorsque vous démarrez un nom de méthode avec deux traits de soulignement Python modifie le nom pour le rendre "privé" et c'est tout ce qu'il fait, il n'applique rien comme les autres langages. Si vous définissez __bar sur Foo, il est toujours accessible de l'extérieur de l'objet via Foo._Foo__bar. Par exemple, on peut faire ceci:

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

Cela explique également l'identifiant "impair" dans le message d'erreur que vous avez reçu.

Vous pouvez le trouver here dans la documentation.

38
Rob Wouters

__bar Est "privé" (dans le sens où son nom a été mutilé ), mais c'est toujours une méthode de Foo, vous devez donc le référencer via self et lui passez self. L'appeler simplement avec une __bar() nue ne fonctionnera pas; vous devez l'appeler comme ceci: self.__bar(). Donc...

>>> 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

Vous pouvez accéder à self.__bar N'importe où dans votre définition Foo, mais une fois en dehors de la définition, vous devez utiliser foo_object._Foo__bar(). Cela permet d'éviter les collisions d'espace de noms dans le contexte de l'héritage de classe.

Si ce n'est pas la raison pour laquelle vous utilisez cette fonctionnalité, vous pouvez reconsidérer son utilisation. La convention pour créer des variables et méthodes "privées" dans Python est de ajouter un trait de soulignement au nom. Cela n'a aucune signification syntaxique, mais il transmet aux utilisateurs de votre code indiquant que la variable ou la méthode fait partie des détails d'implémentation susceptibles de changer.

7
senderle