modules - python packages
Python: módulo ''privado'' en un paquete (4)
La solución que me he propuesto es crear un subpaquete ''privado'' y colocar todos los módulos que deseo ocultar allí. De esta manera, se quedan guardados, dejando la lista de módulos de mypack
más limpia y más fácil de analizar.
Para mí, esto tampoco parece antipónico.
Tengo un paquete mypack
con módulos mod_a
y mod_b
en él. Pretendo que el paquete en sí y mod_a
se importen libremente:
import mypack
import mypack.mod_a
Sin embargo, me gustaría mantener mod_b
para el uso exclusivo de mypack
. Eso es porque existe simplemente para organizar el código interno de este último.
Mi primera pregunta es, ¿es una práctica aceptada en la programación de Python tener módulos ''privados'' como este?
Si es así, mi segunda pregunta es, ¿cuál es la mejor manera de transmitir esta intención al cliente? ¿Prefijo el nombre con un guión bajo (es decir, _mod_b
)? ¿O sería una buena idea declarar un subpaquete como private
y colocar todos esos módulos allí?
Prefijo los módulos privados con un guión bajo para comunicar la intención al usuario. En tu caso, esto sería mypack._mod_b
Esto tiene el mismo espíritu (pero no es completamente análogo a) la recomendación de PEP8 de nombrar módulos de extensión C con un guión bajo cuando está envuelto por un módulo de Python; Es decir, _socket
y socket
.
Python no conoce ni admite estrictamente métodos o clases "privadas" o "protegidas". Existe una convención de que los métodos con un solo guión bajo el prefijo no forman parte de una API oficial, pero no haría esto en clases o archivos, es feo.
Si alguien realmente necesita subclasificar o acceder a mod_b, ¿por qué evitar que lo haga? Siempre puede proporcionar una API preferida en su documentación y el documento en su módulo al que no debe acceder directamente y usar mypack en su lugar.
Si bien no hay palabras clave privadas explícitas, existe una convención para que las funciones privadas comiencen con un solo guión bajo, pero un guión bajo inicial doble hará que otros no puedan llamar fácilmente a la función desde fuera del módulo. Vea lo siguiente de PEP 8
- _single_leading_underscore: weak "internal use" indicator. E.g. "from M
import *" does not import objects whose name starts with an underscore.
- single_trailing_underscore_: used by convention to avoid conflicts with
Python keyword, e.g.
Tkinter.Toplevel(master, class_=''ClassName'')
- __double_leading_underscore: when naming a class attribute, invokes name
mangling (inside class FooBar, __boo becomes _FooBar__boo; see below).
- __double_leading_and_trailing_underscore__: "magic" objects or
attributes that live in user-controlled namespaces. E.g. __init__,
__import__ or __file__. Never invent such names; only use them
as documented.
Para hacer que un módulo completo sea privado, no lo incluya en el archivo __init__.py
.