Python: 'Privé' module dans un package
J'ai un forfait mypack
avec des modules mod_a
et mod_b
en elle. J'ai l'intention de le le package lui-même et mod_a
être importés librement:
import mypack
import mypack.mod_a
Cependant, j'aimerais garder mod_b
pour l'usage exclusif de mypack
. C'est parce qu'il existe simplement pour organiser le dernier code interne.
Ma première question est, est-il une pratique acceptée dans la programmation Python pour avoir "privé" des modules de ce genre?
Si oui, ma deuxième question est, quelle est la meilleure façon de transmettre cette intention pour le client? Dois-je le préfixe du nom par un trait de soulignement (c'est à dire _mod_b
)? Ou serait-ce une bonne idée de déclarer un sous-package private
et placer tous les modules?
Vous devez vous connecter pour publier un commentaire.
Je préfixe modules privés avec un trait de soulignement pour communiquer l'intention de l'utilisateur. Dans votre cas, ce serait
mypack._mod_b
C'est dans le même esprit (mais pas tout à fait analogue) la PEP8 recommandation pour le nom de C-modules d'extension avec un trait de soulignement quand il est enveloppé par un module Python; c'est à dire,
_socket
etsocket
.Even with __all__ set appropriately, internal interfaces (packages, modules, classes, functions, attributes or other names) should still be prefixed with a single leading underscore.
La solution que j'ai réglé sur est de créer un sous-package "privé" et le lieu de tous les modules que je souhaite cacher là-dedans. De cette façon, ils restent rangé dans un coin, laissant
mypack
s'module liste plus propre et plus facile à analyser.Pour moi, cela n'a pas l'air unpythonic soit.
__init__.py
seulement à exposer le "public" des fonctions. Dans PyCharm et Jupyter, de garder les noms des modules internes de listes déroulantes, chaque module doit avoir une fonction avec le même nom que le module, et je doit importer la fonction dans__init__.py
. Vous le savez probablement déjà tout cela, mais si ce n'est pas ici qu'il est. Si vous voulez me faire élargir comme une réponse dites le moi.Alors qu'il n'y a pas explicite privé de mots-clés, il s'agit d'une convention pour la mise privé des fonctions de démarrer avec un seul trait de soulignement, mais un double trait de soulignement va apporter afin que d'autres ne peuvent pas facilement à l'appel de la fonction à partir de l'extérieur du module. Voir la suite de PEP 8
Pour effectuer l'ensemble d'un module de privé, ne sont pas
__init__.py
fichier.__init__.py
"? Voulez-vous dire de ne pas placer la déclarationimport mod_b
dans__init__.py
? Si oui, n'est toujours pas à résoudre mon problème. Le client peut toujours importermod_b
comme un module public:import mypack.mod_b
. Ou voulez-vous dire quelque chose d'autre?private
sousmypack
et de placer tous les modules que je veux "cacher" dans cette. Cela sert mon but de rendre mon code plus facile à explorer (par intellisense, par exemple), en rabattant tous les inutiles peluches.Python n'est pas strictement savoir ou de soutien "privé" ou "protégé" des méthodes ou classes. Il y a une convention que les méthodes préfixé avec un seul trait de soulignement ne font pas partie d'un fonctionnaire de l'API, mais je ne voudrais pas le faire sur des classes ou des fichiers - c'est moche.
Si quelqu'un a vraiment besoin d'une sous-classe ou d'accès mod_b, pourquoi l'empêcher de le faire? Vous pouvez toujours fournir un préféré de l'API dans votre documentation et de document dans votre module que vous ne devriez pas y accéder directement et d'utiliser mypack en place.
mod_b
accessible tout commemod_a
. Cependant, l'imaginer il y a 20 modules semblable àmod_b
. Ainsi, lorsque les types de clientsmypack.
dans l'éditeur, l'intellisense liste de tous les 25 ou privées ainsi que les modules. Cela permettra de rendre mon code plus difficile à explorer. C'est la raison pour laquelle je tiens à "cacher" les modules qui ne sont pas destinés pour le client. Quant à la documentation, les gens préfèrent généralement l'exploration à la lecture de la documentation.mod_b
dans votre__init__.py
. Je vous suggère de regarder le__all__
variable spéciale. Si aucun de ceux que le travail soit fait, le problème est dans Intellisense.mod_b
n'est pas importé dansmypack/__init__.py
, en tapantimport mypack.mod_b
dans le code du client travaille toujours avec succès. C'est parce que Python ne nécessite pas l'importation de modules imbriqués dans le top niveau pour "dot" importations (commemypack.mod_b
) au travail.