281 votes

Définissant les fonctions du module privé en python

Selon http://www.faqs.org/docs/diveintopython/fileinfo_private.html:

Comme la plupart des langages, Python a l' concept de privé éléments:

  • Privé les fonctions, qui ne peut pas être appelée à partir de en dehors de leur module

Cependant, si je définis deux fichiers:

#a.py
__num=1

et:

#b.py
import a
print a.__num

lorsque j'exécute b.py il imprime 1 sans donner aucune exception. Est diveintopython mal, ou le fait que j'ai mal compris quelque chose? Et est-il possible de ne définir un module de fonction en tant que privé?

394voto

Alex Martelli Points 330805

En Python, la "vie privée" dépend de "adultes consentants "" d'accord, vous ne pouvez pas forcer (pas plus que vous pouvez dans la vraie vie;-). Un seul trait de soulignement signifie que vous n'êtes pas censé y accéder "de l'extérieur" -- deux principaux traits de soulignement (w/o de fuite souligne) transmettre le message avec plus de force encore... mais, en fin de compte, cela dépend toujours de convention sociale et le consensus: Python introspection est assez puissant que vous ne pouvez pas les menottes tous les autres programmeur dans le monde pour le respect que vous le souhaitez.

((Btw, si c'est un secret étroitement gardé, bien la en est de même pour le C++: avec la plupart des compilateurs, un simple #define private public ligne avant d' #includeing votre .h le fichier est tout ce qu'il faut pour wily des codeurs à faire de hachage de votre "vie privée"...!-))

322voto

mjv Points 38081

Il peut y avoir confusion entre la classe des soldats et module de soldats.

Un module privé commence avec un seul trait de soulignement
Un tel élément n'est pas copié lors de l'utilisation de l'importation.
Il suffit de retirer un trait de soulignement de l'un.__num de la question de l'exemple et de ne pas s'afficher dans des modules que l'importation d'un.py.

Une classe privée commence avec deux caractères de soulignement (aka dsous soit le double de la sous-score)
Une telle variable a son nom de "déformation" de manière à inclure le nom de la classe etc.
Il peut encore être accessibles de l'extérieur de la logique de classe, par le biais de la déformation d'un nom.
Bien que le nom de déformation peut servir comme un doux dispositif de prévention contre les accès non autorisés, son but principal est d'éviter d'éventuelles collisions de nom avec les membres de la classe de l'ancêtre des classes. Voir Alex Martelli est drôle, mais précis référence à des adultes consentants comme il le décrit de la convention en ce qui concerne ces variables.

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

94voto

Ben Wilhelm Points 291

Cette question n'est pas de répondre pleinement, depuis le module de la vie privée n'est pas purement conventionnelle, et depuis l'utilisation de l'importation peut ou peut ne pas reconnaître le module de la vie privée, selon la façon dont il est utilisé.

Si vous définissez le nom dans un module, les noms vont être importés dans un script qui utilise la syntaxe, 'importer nom_du_module'. Ainsi, en supposant que vous aviez défini correctement dans votre exemple, le module privé, _num, dans un.py, comme c'est le cas..

#a.py
_num=1

..vous seriez en mesure d'accéder à n'b.py avec le nom du module symbole:

#b.py
import a
...
foo = a._num # 1

Pour importer uniquement les non-soldats de un.py, vous devez utiliser la de syntaxe:

#b.py
from a import *
...
foo = _num # throws NameError: name '_num' is not defined

Par souci de clarté, cependant, il est préférable d'être explicite lors de l'importation des noms de modules, plutôt que de les importer tous avec un '*':

#b.py
from a import name1 
from a import name2
...

35voto

Andrew Hare Points 159332

Python permet aux membres privé classe avec le préfixe double trait de soulignement. Cette technique ne fonctionne pas au niveau module donc je pense que c’est une erreur en plongée en Python.

Voici un exemple des fonctions de classe privée :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X