Pregunta

¿Cómo puedo hacer que los métodos y los miembros de datos privados en Python? O no de apoyo Python miembros privados?

¿Fue útil?

Solución

  

9.6. Variables privados

     

variables de instancia “privado” que   no se puede acceder desde el interior excepto   un objeto, no existen en Python.   Sin embargo, hay una convención que es   seguido por la mayoría de código Python: un nombre   prefijado con un guión (por ejemplo   _spam) debe ser tratado como una parte no pública de la API (si   es una función, un método o un conjunto de datos   miembro). Se debe considerar una   detalle de implementación y sujeto a   cambios sin previo aviso.

     

Dado que no es un caso de uso válido para   miembros de la clase-privada (es decir, para evitar   nombrar choques de nombres con nombres   definido por las subclases), hay   soporte limitado para tal mecanismo,   llamada renombrado de nombres. cualquier identificador   de la forma __spam (al menos dos   subrayado iniciales, a lo sumo uno   subrayado de salida) es textualmente   sustituido con _classname__spam, donde   nombre de clase es el nombre de la clase actual   con subrayado inicial (s) despojado.   Este calandrado se realiza sin tener en cuenta   a la posición sintáctica de la   identificador, con tal de que se produce   dentro de la definición de una clase.

Así, por ejemplo ,

class Test:
    def __private_symbol(self):
        pass
    def normal_symbol(self):
        pass

print dir(Test)

es la salida:

['_Test__private_symbol', 
'__doc__', 
'__module__', 
'normal_symbol']

__private_symbol debe considerarse como un método privado, pero aún así sería accesible a través de _Test__private_symbol.

Otros consejos

Las otras respuestas proporcionan los detalles técnicos. Me gustaría hacer hincapié en la diferencia entre la filosofía Python en una mano y lenguajes como C ++ / Java (que supongo que usted está familiarizado con la base de su pregunta).

La actitud general en Python (y Perl para el caso) es que la 'privacidad' de un atributo es una solicitud para el programador en lugar de una valla de alambre de púas por el compilador / intérprete. La idea se resume bien en este correo y se refiere a menudo como "Estamos todos los adultos que consienten", ya que 'supone' que el programador es lo suficientemente responsable para no interferir con las entrañas. Los subrayado iniciales sirven como un amable mensaje diciendo que el atributo es interno.

Por otro lado, si hace desea acceder a los componentes internos para algunas aplicaciones (un ejemplo notable es como generadores de documentación pydoc), usted es libre de hacerlo. Es responsabilidad de usted como un programador para saber lo que está haciendo y hacerlo correctamente y no en la lengua a la fuerza que hace que las cosas es manera.

No hay private de cualesquiera otros mecanismos de protección de acceso en Python. Existe una convención documentado en el guía de estilo de Python para indicar a los usuarios de su clase que no se debe acceder a determinados atributos.

  • _single_leading_underscore: débil indicador de "uso interno". P.ej. from M import * no importa objetos cuyo nombre empieza con un guión bajo.

  • single_trailing_underscore_: usado por convención para evitar conflictos con palabra clave Python, por ejemplo, Tkinter.Toplevel(master, class_='ClassName')

  • __ double_leading_underscore: al nombrar un atributo de clase, invoca nombre mangling (dentro clase FooBar, __boo convierte _FooBar__boo; ver más abajo)

  • .
  

Si el nombre de una función de Python,   método de clase, o atributo comienza con   (Pero no termina con) dos   subraya, que es privado; todo   lo demás es público. Python no tiene ningún concepto   de métodos de clase protegidas (accesible   sólo en su propia clase y descendiente   clases). Los métodos de clase son ya sea   privada (accesible sólo en su propio   clase) o público (accesible desde   en cualquier lugar).

Inmersión en Python

Python no soporta directamente la privacidad. Programador necesita saber cuándo es seguro para modificar el atributo desde fuera, pero de todas formas con el pitón se puede lograr algo como privado con pequeños trucos. Ahora vamos a ver una persona puede poner cualquier cosa privada a él o no.

class Person(object):

    def __priva(self):
        print "I am Private"

    def publ(self):
        print " I am public"

    def callpriva(self):
        self.__priva()

Ahora cuando vamos a ejecutar:

>>> p = Person()
>>> p.publ()
 I am public
>>> p.__priva()
Traceback (most recent call last):
  File "", line 1, in 
    p.__priva()
AttributeError: 'Person' object has no attribute '__priva'
​#Explanation   : You can see  here we are not able to fetch that private method directly.
>>> p.callpriva()
I am Private
#​Explanation  : Here we can access private method inside class​

A continuación, cómo alguien puede tener acceso a esa variable ???
Usted puede hacer como:

>>>p._Person__priva
I am Private

wow, en realidad, si se está pitón cualquier variable comenzando con doble subrayado son “traduce” mediante la adición de un único guión bajo y el nombre de la clase al principio:

Nota: Si no desea cambiar el nombre, pero que todavía quiere enviar una señal para otros objetos que se mantenga alejado, se puede utilizar un solo nombres iniciales de subrayado con un guión inicial no están importados con las importaciones (con estrellas de módulo de importación *)
Ejemplo:

#test.py
def hello():
    print "hello"
def _hello():
    print "Hello private"

#----------------------
#test2.py
from test import *
print hello()
print _hello()

salida ->

hello
Traceback (most recent call last):
  File "", line 1, in 
NameError: name '_hello' is not defined

Ahora bien, si vamos a llamar _hello manualmente.

#test2.py
from test import _hello , hello
print hello()
print _hello()

salida ->

hello
hello private

Por último: Python no tiene realmente un soporte de privacidad equivalente, aunque solo y dobles guiones iniciales hacen en cierta medida le dará dos niveles de privacidad

Esto podría funcionar:

import sys, functools

def private(member):
    @functools.wraps(member)
    def wrapper(*function_args):
      myself = member.__name__
      caller = sys._getframe(1).f_code.co_name
      if (not caller in dir(function_args[0]) and not caller is myself):
         raise Exception("%s called by %s is private"%(myself,caller))
      return member(*function_args)
    return wrapper

class test:
   def public_method(self):
      print('public method called')

   @private
   def private_method(self):
      print('private method called')

t = test()
t.public_method()
t.private_method()

Esto es un poco la l-o-n-g respuesta, pero creo que va a la raíz del problema real aquí - alcance de visibilidad. Simplemente colgar en él, mientras que sudar tinta a través de esto!

Simplemente importar un módulo no necesita necesariamente para obtener el acceso a los desarrolladores de aplicaciones a todas sus clases o métodos; si no puedo ver realmente el código fuente del módulo cómo voy a saber lo que está disponible? Alguien (o algo) tiene que decirme lo que puedo hacer y explicar cómo utilizar estas características que se me permite utilizar, de lo contrario todo es inútil para mí.

Aquellos desarrollo abstracciones de alto nivel basado en clases y métodos a través de los módulos importados fundamentales son presentados con un documento de especificación - no el código fuente real.

La especificación módulo describe todas las características destinadas a ser visible para el desarrollador del cliente. Cuando se trata de grandes proyectos y equipos de proyectos de software, la implementación real de un módulo debe permanecer siempre oculta a personas que hagan uso - es una caja negra con una interfaz con el mundo exterior. Para los puristas OOD, creo que los términos son aficionados a la tecnología "desacoplamiento" y "coherencia". El usuario sólo tiene que saber módulo de los métodos de interfaz sin ser carga con los detalles de implementación.

Un módulo no se debe cambiar sin cambiar primero su documento de especificación subyacente, que puede requerir revisión / aprobación en algunas organizaciones antes de cambiar el código.

Como programador de manía (retirado ahora), que se inicia un nuevo módulo con el documento de especificaciones escritas en realidad como un bloque de comentario gigante en la parte superior del módulo, esta será la parte que el usuario realmente ve en la biblioteca de especificaciones. Ya que sólo yo, todavía tengo que configurar una biblioteca, pero sería bastante fácil de hacer.

Entonces comenzará la codificación escribiendo las diversas clases y métodos, pero sin cuerpos funcionales - sólo declaraciones de impresión nulos como "print ()" - lo suficiente para que el módulo para compilar sin errores de sintaxis. Cuando se completa este paso compilo el nulo finalización de los módulos - este es mi especificación. Si estuviera trabajando en un equipo de proyecto, me gustaría presentar esta especificación / interfaz para su revisión y comentarios antes de proceder a dar cuerpo a cuerpo.

I dar cuerpo a los cuerpos de cada método de uno a la vez y compilar en consecuencia, asegurando errores de sintaxis se fijaron inmediatamente sobre la marcha. Este es también un buen momento para comenzar a escribir una sección de ejecución temporal "principal" en la parte inferior para probar cada método a medida que codificarlo. Cuando la codificación / pruebas, poner todo el código de prueba esté comentada hasta que necesite volver a ser necesario actualizaciones.

En un equipo de desarrollo en el mundo real, el módulo de comentarios de especificaciones que también aparecerá en una biblioteca de control de documentos, pero eso es otra historia. El punto es:. Usted, como cliente de módulo, sólo se ve esta especificación y no el código fuente

PD: mucho antes del comienzo de los tiempos, trabajé en la comunidad de defensa aeroespacial e hicimos algunas cosas bastante fresco, pero cosas como algoritmos y sistemas sensibles lógica de control estaban fuertemente abovedado y cifrado en bibliotecas de software seguro de aúpa. Tuvimos acceso a las interfaces de módulos / paquete, pero no los cuerpos de implementación de la caja negra. Hubo una herramienta de gestión de documentos que maneja todos los diseños a nivel de sistema, especificaciones de software, código fuente y los registros de prueba - se sincroniza todos juntos. El gobierno tenía estrictos estándares de control de calidad de software requisitos. Alguien recuerda un lenguaje llamado "Ada"? Esa es la edad que tengo!

utilizo Python 2.7 y 3.5. Escribí este código:

class MyOBject(object):
    def __init__(self):
        self.__private_field = 10


my_object = MyOBject()
print(my_object.__private_field)

corrieron y tiene:

  

AttributeError: objeto 'myObject' no tiene atributo '__private_field'

Por favor, consulte: https://www.tutorialsteacher.com/python/ -y-acceso-modificadores protegidas privadas-en-pitón

Si desea realizar un métodos o miembros de datos privados en Python, utilizar __setattr __

class Number:
    def __init__(self,value):
        self.my_private = value

    def __setattr__(self, my_private, value):
        # the default behavior
        # self.__dict__[my_private] = value
        raise Exception("can't access private member-my_private")


def main():
    n = Number(2)
    print(n.my_private)

if __name__ == '__main__': 
    main()
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top