2016-06-13 1 views
3

En convention Python, les importations d'un module doivent-elles être considérées comme faisant partie de son interface publique, ou non?Importations python - convention publique ou privée

J'ai un code qui fait cela:

foo.py:

from a import b 

bar.py:

from foo import b 

Je suis en train de décider de refactoriser bar.py pour importer b directement à partir d'un. Je suppose qu'il peut y avoir des cas où vous voulez que foo.py contrôle l'implémentation de b que bar.py utilise. Mais si ce n'est pas le cas, ne serait-il pas préférable que les deux modules l'importent de la même manière?

+0

si vous voulez les rendre privé, vous pouvez toujours faire 'importer b comme _b'. Aussi cette question semble un peu basée sur l'opinion, si vous pouvez penser à un moyen de le reformuler pour être plus objectif qui empêcherait que cela soit fermé comme hors sujet. –

Répondre

2

En convention Python, les importations d'un module doivent-elles être considérées comme faisant partie de son interface publique ou non?

L'API publique d'un module est ce que le module documente son API publique. Si le module foo documents qu'il fournit b, puis b fait partie de son API publique, si b est effectivement défini dans foo ou importé d'ailleurs.

De nombreux modules divisent leur code en plusieurs fichiers et importent toutes les pièces ensemble dans un seul module. Par exemple, le module collections met une partie de son code dans un module C _collections et ne

from _collections import deque, defaultdict 

deque et defaultdict sont clairement partie de l'API publique de collections.

Si un module importe quelque chose qui n'est pas censé faire partie de son API publique, c'est souvent une bonne idée de faire import thing as _thing, en mettant un trait de soulignement pour signaler que la chose importée est un détail d'implémentation.

2

Point de vue de la documentation. La convention est que tout ce qui ne commence pas par underscore est public. Si vous souhaitez marquer un symbole d'importation comme privé, aliasz-le avec un caractère de soulignement tel que from a import b as _b. Il y a une alternative. Vous pouvez utiliser __all__ à la place, pour déclarer les symboles que vous considérez comme publics. Même si techniquement cela ne concerne que from module import *, c'est aussi une bonne déclaration d'intention.

Point de vue de dépendance. Je ne recommanderais pas de compliquer le graphe de dépendance sans raison valable, car sinon, il y a plus de chances de tomber sur des problèmes d'importation circulaire plus tard dans le processus de développement.

Selon Zen of Python, explicite est mieux que implicite et simple est mieux que complexe. Donc, si le module a fournit le symbole b, il est raisonnable que tous les modules qui utilisent b l'importent de a.

0

définition du module en mode ninja

def defmod(): 
    global foo 
    import sys 
    def foo(): return sys.path 
defmod() 
del defmod