Estoy codificando un pequeño módulo de Python compuesto por dos partes:
- algunas funciones que definen una interfaz pública,
- una clase de implementación utilizada por las funciones anteriores, pero que no es significativa fuera del módulo.
Al principio, decidí "ocultar" esta clase de implementación definiéndola dentro de la función que la usa, pero esto dificulta la legibilidad y no se puede usar si varias funciones reutilizan la misma clase.
Entonces, además de los comentarios y las cadenas de documentos, ¿existe algún mecanismo para marcar una clase como "privada" o "interna"? Soy consciente del mecanismo de subrayado, pero según tengo entendido, solo se aplica a las variables, la función y el nombre de los métodos.
fuente
En breve:
No puede hacer cumplir la privacidad . No hay clases / métodos / funciones privados en Python. Al menos, no la privacidad estricta como en otros lenguajes, como Java.
Solo puede indicar / sugerir privacidad . Esto sigue una convención. La convención de Python para marcar una clase / función / método como privada es anteponerla con un _ (guión bajo). Por ejemplo,
def _myfunc()
oclass _MyClass:
. También puede crear pseudoprivacidad precediendo el método con dos guiones bajos (por ejemplo:)__foo
. No puede acceder al método directamente, pero aún puede llamarlo a través de un prefijo especial usando el nombre de clase (por ejemplo:)_classname__foo
. Por lo tanto, lo mejor que puede hacer es indicar / sugerir privacidad, no imponerla.Python es como Perl a este respecto. Parafraseando una famosa línea sobre la privacidad del libro de Perl, la filosofía es que debes permanecer fuera de la sala de estar porque no fuiste invitado, no porque se defienda con una escopeta.
Para más información:
fuente
Defina
__all__
, una lista de nombres que desea exportar ( ver documentación ).fuente
Un patrón que a veces uso es este:
Definir una clase:
Cree una instancia de la clase, sobrescribiendo el nombre de la clase:
Defina símbolos que expongan la funcionalidad:
Elimina la propia instancia:
Ahora tienes un módulo que solo expone tus funciones públicas.
fuente
La convención es anteponer "_" a las clases, funciones y variables internas.
fuente
Para abordar el tema de las convenciones de diseño, y como dijo Christopher, realmente no existe algo como "privado" en Python. Esto puede sonar retorcido para alguien que proviene de C / C ++ (como yo hace un tiempo), pero eventualmente, probablemente se dará cuenta de que seguir las convenciones es suficiente.
Ver algo que tiene un guión bajo al frente debería ser una buena pista para no usarlo directamente. Si le preocupa el desorden de la
help(MyClass)
salida (que es lo que todos miran cuando buscan cómo usar una clase), los atributos / clases subrayados no se incluyen allí, por lo que terminará con su interfaz "pública" descrita.Además, tener todo lo público tiene sus propias ventajas increíbles, como, por ejemplo, puede realizar pruebas unitarias prácticamente cualquier cosa desde el exterior (lo que realmente no puede hacer con las construcciones privadas de C / C ++).
fuente
Utilice dos guiones bajos para prefijar nombres de identificadores "privados". Para las clases de un módulo, utilice un solo subrayado inicial y no se importarán utilizando "from module import *".
(No existe el verdadero "privado" en Python. Por ejemplo, Python simplemente modifica automáticamente los nombres de los miembros de la clase con guiones bajos dobles para que sean
__clssname_mymember
. Entonces, en realidad, si conoce el nombre mutilado, puede usar la entidad "privada" de todos modos . Vea aquí. Y, por supuesto, puede elegir importar manualmente clases "internas" si lo desea).fuente