Pregunta

Estoy codificar un módulo de Python pequeña compuesta de dos partes:

  • algunas de las funciones que definen una interfaz pública,
  • una clase de implementación utilizado por las funciones anteriores, pero que no es significativa fuera del módulo.

Al principio, me decidieron a "ocultar" esta clase de implementación al definirlo dentro de la función de usarlo, pero esto dificulta la lectura y no se pueden utilizar en caso de múltiples funciones reutilizar la misma clase.

Por lo tanto, además de comentarios y cadenas de documentación, ¿existe un mecanismo para marcar una clase como "privado" o "interno"? Soy consciente del mecanismo guión bajo, pero como yo lo entiendo que sólo se aplica a las variables, la función y los métodos de nombre.

¿Fue útil?

Solución

Utilice un único prefijo de subrayado:

class _Internal:
    ...

Esta es la convención oficial de Python para los símbolos 'internos'; "De módulo de importación *" no importa objetos subrayado prefijada.

Edit: Referencia a la sola subrayar convención

Otros consejos

En resumen:

  1. No se puede hacer cumplir la privacidad . No hay clases / métodos / funciones privadas en Python. Al menos, no estricta privacidad como en otros idiomas, como Java.

  2. Puede sólo indican / sugerir privacidad . Esto sigue a una convención. La convención pitón para el marcado a / función / método de clase como privado es prologar con una _ (subrayado). Por ejemplo, def _myfunc() o class _MyClass:. También se pueden crear pseudo-privacidad por prologar el método con dos guiones (por ejemplo: __foo). No se puede acceder al método directamente, pero todavía se puede llamar a través de un prefijo especial utilizando el nombre de clase (por ejemplo: _classname__foo). Así que lo mejor que puede hacer es indicar / sugerir privacidad, no cumplir.

Python es como Perl en este sentido. Parafraseando una famosa frase acerca de la privacidad del libro de Perl, la filosofía es que debe permanecer fuera de la sala de estar, ya que no fueron invitados, no porque se defiende con una escopeta.

Para más información:

Definir __all__, una lista de nombres que desea exportar ( ver la documentación ).

__all__ = ['public_class'] # don't add here the 'implementation_class'

Un modelo que a veces uso es la siguiente:

Definir una clase:

class x(object):
    def doThis(self):
        ...
    def doThat(self):
        ...

Crea una instancia de la clase, sobrescribir el nombre de clase:

x = x()

Definir símbolos que exponen la funcionalidad:

doThis = x.doThis
doThat = x.doThat

Eliminar la instancia de sí mismo:

del x

Ahora usted tiene un módulo que sólo expone sus funciones públicas.

La convención es prepend "_" a internos clases, funciones y variables.

Para abordar la cuestión de convenciones de diseño, y como dijo Christopher, en realidad no hay tal cosa como "privado" en Python. Esto puede sonar trenzado para alguien que viene de C / C ++ de fondo (como yo hace un tiempo), pero con el tiempo, es probable que se dará cuenta de un montón siguiendo las convenciones es suficiente.

Ver algo teniendo un guión bajo delante debe ser un buen indicio suficiente como para no utilizarla directamente. Si usted está preocupado con estorbar la salida help(MyClass) (que es lo que cada uno mira a la hora de buscar en el uso de una clase), los atributos subrayados / clases no están incluidos allí, así que va a terminar sólo tener la interfaz de "público" describió .

Además, tener todo lo público tiene sus propias ventajas impresionantes, como por ejemplo, puede unidad de prueba de casi cualquier cosa desde fuera (que realmente no se puede hacer con C / C ++ construcciones privadas).

Utilice dos guiones para prefijar los nombres de los identificadores "privadas". Para las clases en un módulo, utilice un solo subrayado inicial y no van a ser importados utilizando "de importación de módulo *".

class _MyInternalClass:
    def __my_private_method:
        pass

(no hay tal cosa como la verdadera "privado" en Python. Por ejemplo, Python solo destroza automáticamente los nombres de los miembros de la clase con subrayado doble para ser __clssname_mymember. Así que en realidad, si se conoce el nombre revuelto puede utilizar el " entidad privada" de todos modos. ve aquí. Y, por supuesto, se puede elegir para importar manualmente clases "internos" si desea).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top