main.py: strong> subone.py: strong> p> subtwo.py: strong> p> exécuté refactorise son utilisation main.py: strong> p> subone.py: strong> p> mais il va em> imprimer 'de main.py: def'. (Cela fonctionne lorsque vous utilisez Pourquoi ça marche de cette façon? Il semble que, une fois est-ce parce que c'est une mauvaise programmation d'avoir des modules importés dépendent l'un de l'autre Sans passer par leur module «parent»? Y a-t-il un autre moyen standard de faire cela? P> Je comprends maintenant que le premier exemple ne fonctionnera pas car la ligne Mais qu'en est-il de ce sujet: P> subone.py: strong> p> Je pense que depuis python main.py code> jette un
nomError: nom "subone" n'est pas défini code>. Je m'attendais à imprimer «ABC». P>
à partir de code>
Importer code> et les classes n'aident pas: P>
importer code> aussi.) P>
subone code> est importé, il doit être disponible pour
subtwo code>. P>
Mise à jour: h1>
impression subone.a code> ne reconnaît pas le nom
subone code>, ce n'est pas dans
subtwo code> 'S strong> Espace de noms (même s'il est dans
Main.py code>'s), et il est appelé à partir de l'intérieur du module
subtwo code>. Cela peut être corrigé en utilisant
importer subone code> en haut de
subtwo.py code> - il ne rechargera pas le module mais l'ajoutera à
subtwo Code> 's Espace de noms SO
SUBTWO code> peut l'utiliser. P>
wrap code> et
nugget code> sont tous deux chargés directement dans
Main code> 'S Espace de noms, qu'ils utiliseraient
Main code> S et être capables de se référencer, mais il jette un
nomError: nom' nugget 'n'est pas défini code>. Est-ce parce que
wrap code> est évalué / vérifié à partir de dans em>
SUBTWO code> SUBTWO code> avant d'être chargé dans
Main code> S ? p> p>
5 Réponses :
Le En ce qui concerne les pratiques de programmation, Subtwo code> Espace de noms sera totalement vide que si vous importez
subone code> dans celui-ci. P>
subone code> et
subtwo code> peut dépendre de l'autre si vous le souhaitez, il vous suffit de les lier explicitement (avec un
importer < / code>) p>
D'accord, mais pourquoi ne fonctionne-t-il pas même lors de l'utilisation de - importation, qui charge tout dans l'espace de noms de l'établissement principal?
Peu importe, lorsque subtwo code> est exécuté (lorsque le document
Importez code>'s), rien n'est dans SON i> Espace de noms.
Cela pourrait aider à se rappeler que importer code> dans python n'est pas comme
inclure code> dans d'autres langues.
Pouvez-vous expliquer pourquoi vous avez envie de subone doit être disponible pour subtwo, lorsque subone a été importé par principal? Comme c'est le cas, subtwo.py peut être compilé sans savoir ce que Main.py a importé. P>
Également, si un deuxième programme importe SubTwo.py, devrait-il subverser la connaissance de subone dépendent de laquelle de deux programmes principaux importateurs de subtwo? Cela réduirait la réutilisabilité de subtwo. P>
On dirait que vous envisagez de penser à la compilation en tant que processus avec un ordre défini, accumulant des informations sur l'état: Compiler Main.py, au cours de laquelle nous compilons / importées subone.py, accumulant des informations de celui-ci, puis nous compilons / Importer subtwo.py, en utilisant les informations que nous avons déjà accumulées. p>
Au lieu de cela, la compilation de chaque module est indépendante des autres, à moins que des dépendances ne soient déclarées. Cela facilite beaucoup la réutilisation et maintenir le code: il y a moins de dépendances cachées. P>
est-ce parce que c'est une mauvaise programmation de avoir des modules importés dépendent de chaque autre sans passer à travers leur Module 'Parent'? P> blockQuote>
Pas aussi telle ... C'est juste une mauvaise programmation pour que le module 2 dépendent du module 1 sans dire que em>, c'est-à-dire, sans module 2 déclarant "je dépends du module 1". P>
Ah, je vois. La façon dont vous décrivez cela aide. Je pense que j'ai été habitué à code> de PHP Inclure code> et nécessite des instructions code>, qui incorporent directement le code. Au lieu de cela, les modules sont des objets qui doivent être appelés.
@WILLELL: Je n'ai jamais utilisé php, mais C est similaire avec le préprocesseur #include code> juste coller tout le fichier là-bas. Quoi qu'il en soit, une sorte de dépendance implicite comme celle-là ne semble tout simplement pas intelligente quelle que soit la langue.
@willell, cela a du sens ... la façon dont vous y envisagez correspond à la manière dont les mécanismes PHP et C incluent. Cependant, vous pouvez voir comment cela conduit à des dépendances difficiles à tracer ... afin de savoir quel fichier b dépend de, vous devez regarder tous les endroits où le fichier B est inclus. Il y a donc une différence fondamentale entre "y compris un fichier" et "importer un module". Le premier est davantage une insertion simple et littérale d'une chaîne de texte, inconsciente des conséquences sémantiques. Ce dernier est plus d'une liaison conceptuelle d'un composant de programme à un autre.
Ouais, je gocha. Ce que vous appelez la liaison conceptuelle, c'est une grande partie de la raison pour laquelle j'utilise Python de toute façon. La seule chose à laquelle je suis toujours confondue sur: si à partir de l'importation code> charge tous les objets au niveau du module dans l'espace de noms actuel, pourquoi les objets ne peuvent-ils pas se référer mutuellement? Est-ce parce que ces objets sont évalués dans leurs modules respectifs avant qu'ils ne soient chargés dans le module actuel?
Si vous avez modifié votre subtwo.py de cette façon, il fonctionnera lorsque vous faites subonter.a dans subtwo.py, vous essayez d'accéder à l'espace de noms subone dans subtwo.py et dans l'espace de noms "subone", il devrait y avoir un attribut "A". P> Lorsque vous le faites - importer subone dans subtwo.py, alors subone est ajouté à l'espace de noms et à l'espace de noms subomonal a attributé A. alors subone.Une fonctionnera. P> Je suggérerais également que vous jouiez avec DIR () pour voir comment les espaces de noms sont ajoutés. p> dans subtwo.py, vous pouvez faire ce qui suit : p> de la même manière, essayez d'ajouter "impression Dir ()" avant et après vos relevés d'importation et que l'idée devrait être claire pour vous. P> "Importer x" ajoute 'x' aux modules actuels
Espace de noms alors que "de x importation *" sera
Ajoutez tous les attributs de niveau de module
directement dans l'espace de noms de module actuel P>
blockQuote> donc dans votre premier exemple ci-dessus de MAIN.PY, subone.py et subtwo.py, l'espace de noms dans Main.py contiendra "subone" et "subtwo" pendant que subtwo.py aura Un espace de nom vide et ne peut pas accéder à subone.a. em> p> [EDIT: quelques explications supplémentaires]
Considérons les fichiers suivants:
main.py p> subone.py p> subtwo.py p> et la sortie d'exécuter Main.py: p> certaines observations fortes> p>
blockQuote>
C'est très utile. Dir () fait clairement clairement les choses pour moi. Ma seule question (comme je l'ai commentée ci-dessous) est que si "à partir de x importer *" ajoute tous les attributs de niveau de module directement dans l'espace de noms actuel, pourquoi ces attributs ne peuvent-ils pas se rencontrer?
Cette importation ne modifie pas la portée des attributs, il copie simplement leur définition à la portée locale.
@willell: Ignacio Vazquez-Abrams est correct. J'aurais dû être plus clair. Ce n'est pas la même chose que la copie du code que cela se produise en cas de #include dans "C". Les modules importés sont déjà chargés et évalués. Si vous aviez une déclaration d'impression dans un module importé, il aurait déjà été évalué.
@Ignacio: Vous dites que chaque attribut a son propre espace de noms, hérité du module it provenait?
@pyfunc: gotcha. Donc, dans mon troisième exemple dans ma question mise à jour, wrap code> et
nugget code> sont évalués (et soulevez donc la nomEError) avant que leurs définitions ne soient chargées dans
principal code> 's Espace de noms?
Chaque attribut a sa propre portée, que la référence transporte avec elle.
@Ignacio Vazquez-Abrams: @willell: +1 qui explique tout cela.
En ce qui concerne votre deuxième exemple, "Main.py" connaît environ Je pense que cela aiderait à en penser de cette façon. Chaque module (fichier) doit fonctionner comme si seuls les seuls autres modules existants sont ceux qu'il importait. Dans ce cas "subtwo.py" ne pourra pas fonctionner en soi, car il n'a pas importé Nugget code> mais "subtwo.py" ne pas. p>
nugget code>. Essentiellement "subtwo.py" ne sait pas ce que "Main.py" sait. Cela ne devrait pas, parce que cela pourrait être appelé de n'importe qui, et il ne peut pas compter sur quelqu'un d'autre importer les choses qu'elle a besoin. P>
En effet, les modules importés ont ses propres espaces de noms distincts. Ce que vous avez écrit, c'est beaucoup comme: Les modules ont leurs espaces de noms localement, et lorsque vous utilisez Néanmoins - ce que vous essayez de faire est une très mauvaise pratique. Évitez d'utiliser des variables globales et plus sur ce:
https://docs.python.org/3/reference/import.html P> https://bytebaker.com/2008/07 / 30 / Python-Namespaces / P> http: // www.diveintopthon.net/html_processing/locals_and_globals.html p> et peut-être: http://sebastianraschka.com/articles/2014_python_scope_and_namespaces.html p> p> à partir de subone import * code> vous importez l'espace de noms uniquement sur
Main.py code> Espace de noms qui ne peut pas être accédé par
Subtwo code>. p>
importer * code>, juste parce que vous aurez de plus en plus confus comme maintenant. P>
Votre encapsulation semble vraiment cassée ...
Vous devez rechercher le scopage lexical. L'idée de base est que le code a accès à ce qu'il peut «voir» dans le code source. Que se passe-t-il au moment de l'exécution n'a rien à voir avec ça.