240 votos

La definición privado de las funciones de un módulo en python

De acuerdo a http://www.faqs.org/docs/diveintopython/fileinfo_private.html:

Como la mayoría de los lenguajes, Python tiene la concepto de elementos privados:

  • Privado funciones, que no puede ser llamado desde fuera de su módulo

Sin embargo, si defino dos archivos:

#a.py
__num=1

y:

#b.py
import a
print a.__num

cuando ejecuto b.py imprime 1 sin dar ninguna excepción. Es diveintopython mal, o no me malinterprete algo? Y hay alguna manera de hacer definir un módulo de función como privada?

325voto

Alex Martelli Puntos 330805

En Python, "privacidad" depende de "adultos" de los niveles de acuerdo - no se puede forzar (más de lo que puede en la vida real;-). Una sola subrayado significa que no supone que para acceder a él desde "fuera" -- dos principales caracteres de subrayado (w/o trailing subraya) llevar el mensaje con más fuerza aún... pero, al final, todavía depende de una convención social y el consenso: Python introspección es tan fuerte que no se puede atar de manos a todos los demás programador en el mundo el respeto que usted desea.

((Por cierto, aunque es un secreto bien guardado, de la misma tiene para C++: con la mayoría de los compiladores, una simple #define private public línea antes de #includeing su .h archivo es todo lo que necesita para wily codificadores para hacer hash de su "privacidad"...!-))

290voto

mjv Puntos 38081

Puede haber confusión entre la clase de los soldados y el módulo de soldados.

Un módulo privado comienza con un solo carácter de subrayado
Tal elemento no se copian junto al uso de la importación.
Simplemente quite un carácter de subrayado de la una.__número de la pregunta del ejemplo y no se mostrará en los módulos que importar un.py.

Una clase privada comienza con dos guiones bajos (aka dunder es decir, d-dogvble bajo-score)
Una variable de este tipo tiene su nombre "trastoca" para incluir el nombre de la clase, etc.
Todavía se puede acceder fuera de la lógica de clase, a través de la trastoca nombre.
Aunque el nombre de destrozarlo puede servir como un leve dispositivo de prevención contra el acceso no autorizado, su propósito principal es prevenir posibles colisiones de nombres con los miembros de la clase del antepasado clases. Ver a Alex Martelli curioso, pero la referencia precisa a los adultos como él lo describe de la convención en lo que respecta a estas 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
>>>

82voto

Ben Wilhelm Puntos 291

Esta pregunta no fue respondido, ya que el módulo de la privacidad no es puramente convencional, y dado que el uso de importación puede o no puede reconocer módulo de privacidad, dependiendo de cómo se utiliza.

Si se define privado nombres en un módulo, los nombres va a ser importados en cualquier secuencia de comandos que utiliza la sintaxis, 'importar nombre_modulo'. Por lo tanto, suponiendo que había definido correctamente en tu ejemplo el módulo privado, _num, en un.py, como así..

#a.py
_num=1

..usted sería capaz de acceder a ella en b.py con el nombre del módulo símbolo:

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

Para importar sólo no privados de una.py, debe utilizar el de la sintaxis:

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

En aras de la claridad, sin embargo, es mejor ser explícito, cuando la importación de los nombres de los módulos, en lugar de importar todos ellos con un '*':

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

29voto

Andrew Hare Puntos 159332

Python permite privado de la clase de los miembros con el carácter de subrayado doble prefijo. Esta técnica no funciona en un nivel de módulo, así que estoy pensando que esto es un error en la Inmersión En Python.

Aquí es un ejemplo de clase privada funciones:

class foo():
    def bar(self): pass
    def __bar(self): pass

f = foo()
f.bar()   # this call succeeds
f.__bar() # this call fails

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X