Je suis en train de coder un petit module Python composé de deux parties:
- certaines fonctions définissant une interface publique,
- une classe d'implémentation utilisée par les fonctions ci-dessus, mais qui n'a pas de sens en dehors du module.
Au début, j'ai décidé de «cacher» cette classe d'implémentation en la définissant dans la fonction qui l'utilise, mais cela entrave la lisibilité et ne peut pas être utilisée si plusieurs fonctions réutilisent la même classe.
Donc, en plus des commentaires et des docstrings, existe-t-il un mécanisme pour marquer une classe comme "privée" ou "interne"? Je connais le mécanisme de soulignement, mais si je comprends bien, il ne s'applique qu'aux variables, aux fonctions et aux noms de méthodes.
la source
En bref:
Vous ne pouvez pas appliquer la confidentialité . Il n'y a pas de classes / méthodes / fonctions privées en Python. Au moins, pas de confidentialité stricte comme dans d'autres langages, tels que Java.
Vous ne pouvez indiquer / suggérer la confidentialité . Cela suit une convention. La convention python pour marquer une classe / fonction / méthode comme privée est de la faire précéder d'un _ (trait de soulignement). Par exemple,
def _myfunc()
ouclass _MyClass:
. Vous pouvez également créer une pseudo-confidentialité en faisant précéder la méthode de deux traits de soulignement (par exemple:)__foo
. Vous ne pouvez pas accéder directement à la méthode, mais vous pouvez toujours l'appeler via un préfixe spécial en utilisant le nom de classe (par exemple:)_classname__foo
. Donc, le mieux que vous puissiez faire est d'indiquer / suggérer la confidentialité, et non de la faire respecter.Python est comme Perl à cet égard. Pour paraphraser une ligne célèbre sur la vie privée du livre Perl, la philosophie est que vous devriez rester en dehors du salon parce que vous n'avez pas été invité, pas parce qu'il est défendu avec un fusil de chasse.
Pour plus d'informations:
la source
Définissez
__all__
, une liste de noms que vous souhaitez exporter ( voir documentation ).la source
Un modèle que j'utilise parfois est le suivant:
Définissez une classe:
Créez une instance de la classe en écrasant le nom de la classe:
Définissez des symboles qui exposent la fonctionnalité:
Supprimez l'instance elle-même:
Vous avez maintenant un module qui expose uniquement vos fonctions publiques.
la source
La convention est précédée de "_" aux classes, fonctions et variables internes.
la source
Pour aborder la question des conventions de conception, et comme l'a dit Christopher, il n'y a vraiment rien de tel que «privé» en Python. Cela peut sembler tordu pour quelqu'un qui vient de fond C / C ++ (comme moi il y a quelque temps), mais finalement, vous réaliserez probablement que les conventions suivantes sont suffisantes.
Voir quelque chose avec un trait de soulignement devant devrait être un indice suffisant pour ne pas l'utiliser directement. Si vous êtes préoccupé par l'encombrement de la
help(MyClass)
sortie (ce que tout le monde regarde lors de la recherche sur la façon d'utiliser une classe), les attributs / classes soulignés ne sont pas inclus ici, donc vous finirez par avoir simplement votre interface "publique" décrite.De plus, avoir tout ce qui est public a ses propres avantages, comme par exemple, vous pouvez tester à peu près n'importe quoi de l'extérieur (ce que vous ne pouvez pas vraiment faire avec les constructions privées C / C ++).
la source
Utilisez deux traits de soulignement pour préfixer les noms d'identificateurs «privés». Pour les classes d'un module, utilisez un seul trait de soulignement et elles ne seront pas importées à l'aide de "from module import *".
(Il n'y a pas de véritable "privé" en Python. Par exemple, Python modifie automatiquement les noms des membres de la classe avec des doubles traits de soulignement
__clssname_mymember
. Donc, vraiment, si vous connaissez le nom mutilé, vous pouvez quand même utiliser l'entité "privée" . Voir ici. Et bien sûr, vous pouvez choisir d'importer manuellement les classes "internes" si vous le souhaitez).la source