557 votos

El significado de un individual y un doble subrayado antes de un nombre de objeto en Python

Quiero aclarar esto de una vez por todas. Por favor alguien puede explicar el significado exacto de haber subrayado iniciales antes de un nombre del objeto en Python? También explique la diferencia entre un individual y un doble subrayado. También, hace que el significado de la misma estancia, si el objeto en cuestión es una variable, una función, un método, etcétera?

506voto

Andrew Keeton Puntos 6268

Solo Carácter De Subrayado

Los nombres, en una clase, con un subrayado son simplemente para indicar a otros programadores que el atributo o método está destinado a ser privado. Sin embargo, nada especial se hace con el mismo nombre.

Citar PEP-8:

_single_leading_underscore: débil "uso interno" en el indicador. Por ejemplo. from M import * no importar objetos cuyo nombre comienza con un carácter de subrayado.

Doble Carácter De Subrayado (Nombre De Destrozarlo)

Desde el Python docs:

Cualquier identificador de la forma __spam (al menos dos de los principales caracteres de subrayado, a más de un trailing subrayado) es textualmente sustituido con _classname__spamdonde classname es el actual nombre de la clase con subrayado(s) pelados. Esta destrozando se realiza sin considerar la posición sintáctica del identificador, por lo que puede utilizarse para definir la clase de instancia privada y las variables de la clase, los métodos, las variables almacenadas en variables globales, e incluso las variables almacenadas en las instancias. privado a esta clase de instancias de otras clases.

Y una advertencia desde la misma página:

Nombre destrozando está destinado a dar clases de una manera fácil definir el concepto de "privado" variables de instancia y métodos, sin tener que preocuparse acerca de las variables de instancia definida por las clases derivadas, o ensuciar con las variables de instancia por el código externo a la clase. Tenga en cuenta que el planchado de que las reglas están diseñadas principalmente para evitar accidentes; sin embargo, es posible para un alma decidida para acceder o modificar una variable que se considera privado.

Ejemplo

>>> class MyClass():
...     def __init__(self):
...             self.__superprivate = "Hello"
...             self._semiprivate = ", world!"
...
>>> mc = MyClass()
>>> print mc.__superprivate
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: myClass instance has no attribute '__superprivate'
>>> print mc._semiprivate
, world!
>>> print mc.__dict__
{'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'}

203voto

Alex Martelli Puntos 330805

Excelentes respuestas hasta ahora, pero algunas cositas que faltan. Una sola subrayado no es exactamente simplemente una convención: si utiliza from foobar import *, y el módulo foobar no define un __all__ de la lista, los nombres importados desde el módulo no incluyen a aquellos con un subrayado. Digamos que es principalmente una convención, ya que este caso es un bonito rincón oscuro;-).

El líder de subrayado convención es ampliamente utilizado no sólo para los privados de nombres, sino también por lo que C++ llamaría protegidas , por ejemplo, los nombres de los métodos que están totalmente destinadas a ser reemplazado por las subclases (incluso los que tienen que ser reemplazado, ya que en la clase base que raise NotImplementedError!-) a menudo son solo líder-subrayan los nombres para indicar el código usando las instancias de esa clase (o subclases) que dijo que los métodos no están destinados a ser llamada directamente.

Por ejemplo, para crear un hilo de seguridad de la cola con un diferente sistema de colas disciplina de FIFO, una de las importaciones de la Cola, las subclases Queue.Queue, y anula dichos métodos como _get y _put; "código de cliente" nunca llama a los ("gancho"), los métodos, sino más bien el ("organización") métodos públicos como put y get (esto se conoce como el Método de Plantilla patrón de diseño -- véase, p. ej. aquí una interesante presentación basada en un video de una charla de la mina sobre el tema, con la adición de la sinopsis de la transcripción).

149voto

Ned Batchelder Puntos 128913

__foo__: esta es sólo una convención, una manera de que el sistema Python el uso de nombres que no entre en conflicto con los nombres de usuario.

_foo: esta es sólo una convención, una forma para que el programador para indicar que la variable es privada (lo que significa que en Python).

__foo: esto ha significado real: el intérprete sustituye este nombre con _classname__foo como una forma de asegurarse que el nombre no se superponen con un nombre similar en otra clase.

No hay otra forma de guiones tienen un significado en Python mundo.

No hay ninguna diferencia entre la clase, una variable global, etc en estos convenios.

63voto

NickCSE Puntos 25

._variable es semiprivado y que significa para la convención

.__variable se considera superprivate y consigue namemangled para evitar el acceso accidental

.__variable__ normalmente está reservado para builtin métodos o variables

Usted todavía puede tener acceso a .__superprivate variables si usted quiere desesperadamente. El doble subraya namemangles, o cambia el nombre de la variable a algo como instance._className__superprivate

Ejemplo:

class Test(object):
    def __init__(self):
        self.__a = 'a'
        self._b = 'b'

>>> t = Test()
>>> t._b
'b'

t._b es accesible, ya que sólo se oculta por la convención

>>> t.__a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Test' object has no attribute '__a'

t.__a no se encuentra porque ya no existe debido a la namemangling

>>> t._Test__a
'a'

Accediendo instance._className__variable en lugar de sólo el superprivate nombre, usted puede acceder al valor oculto

15voto

Tim D Puntos 498

A veces tienen lo que parece ser una tupla con un carácter de subrayado inicial como en

def foo(bar):
    return _('my_' + bar)

En este caso, lo que pasa es que _() es un alias para una localización de la función que opera en el texto para ponerlo en el lenguaje adecuado, etc. basándose en la configuración regional. Por ejemplo, la Esfinge que hace esto, y vas a encontrar entre las importaciones

from sphinx.locale import l_, _

y en sphinx.locale, _() es asignado como un alias de algunos de localización de la función.

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