Comment fonctionne exactement l'importation de Python?
J'ai deux situations spécifiques où je ne comprends pas comment l'importation fonctionne en Python:
1ère situation spécifique:
Lorsque j'importe le même module dans deux scripts Python différents, le module n'est pas importé deux fois, n'est-ce pas? La première fois que Python le rencontre, il est importé, et la deuxième fois, vérifie-t-il si le module a été importé, ou fait-il une copie?
2ème situation spécifique:
Considérons le module suivant, appelé bla.py:
a = 10
Et puis, nous avons foo.py, un module qui importe bla.py:
from bla import *
def Stuff ():
return a
Et après cela, nous avons un script appelé bar.py, qui est exécuté par l'utilisateur:
from foo import *
Stuff() #This should return 10
a = 5
Stuff()
Ici, Je ne sais pas: Stuff() renvoie-t-il 10 ou 5?
2 réponses
Partie 1
Le module n'est chargé qu'une seule fois, il n'y a donc pas de perte de performance en l'important à nouveau. Si vous vouliez réellement qu'il soit chargé/analysé à nouveau, vous devrez reload() le module.
La première place cochée est
sys.modules, le cache de tous les modules qui ont été importés précédemment. [source]
Partie 2
from foo import * importe a dans la portée locale. Lors de l'attribution d'une valeur à a, elle est remplacée par la nouvelle valeur - mais la variable foo.a d'origine n'est pas touchée.
Donc, sauf si vous import foo et modifiez foo.a, les deux appels retourneront la même valeur.
Pour un type mutable tel qu'une liste ou un dict, il serait différent, le modifier affecterait en effet la variable d'origine - mais lui attribuer une nouvelle valeur ne modifierait toujours pas foo.whatever.
Si vous voulez des informations plus détaillées, jetez un oeil à http://docs.python.org/reference/executionmodel.html:
Les constructions suivantes lient les noms: les paramètres formels aux fonctions, les instructions d'importation , les définitions de classe et de fonction (celles-ci lient le nom de classe ou de fonction dans le bloc de définition) et les cibles qui sont des identificateurs si elles se produisent dans une affectation, pour l'en-tête de boucle,
Les deux gras les sections sont les plus pertinentes pour vous: d'Abord le nom de a est lié à la valeur de foo.a lors de l'importation. Ensuite, en faisant a = 5, le nom a est lié à 5. Puisque la modification d'une liste / dict ne provoque aucune liaison, ces opérations modifieraient celle d'origine (b et foo.b sont liés au même objet sur lequel vous opérez). Assigner un nouvel objet à {[14] } serait à nouveau une opération de liaison et séparerait donc b de foo.b.
Il est également intéressant de noter ce que exactement l'instruction import fait:
-
import foolie le nom du module à l'objet module dans la portée actuelle, donc si vous modifiezfoo.whatever, Vous travaillerez avec le nom dans ce module - toutes les modifications / affectations affecteront la variable dans le module. -
from foo import barlie uniquement le(s) nom (S) donné (s) (c'est-à-direfoorestera non lié) à l'élément portant le même nom dansfoo- donc les opérations surbarse comportent comme expliqué précédemment. -
from foo import *se comporte comme le précédent un, mais il importe tous les noms globaux qui ne sont pas préfixés par un trait de soulignement. Si le module définit__all__, seuls les noms à l'intérieur de cette séquence sont importés.
Partie 3 (qui n'existe même pas dans votre question :p)
La documentation python est extrêmement bonne et généralement verbeuse-vous trouvez une réponse sur presque toutes les questions possibles liées au langage. Voici quelques liens:
- http://docs.python.org/reference/datamodel.html (classes, propriétés, méthodes magiques, etc.) ()
- http://docs.python.org/reference/executionmodel.html (Comment fonctionnent les variables en python)
- http://docs.python.org/reference/expressions.html
-
http://docs.python.org/reference/simple_stmts.html (déclarations telles que
import,yield) -
http://docs.python.org/reference/compound_stmts.html (bloc de déclarations telles que
for,try,with)
, pour répondre À votre première question:
Non, python n'est pas' importé ' deux fois. Lorsque python charge un module, il vérifie le module dans sys.modules. Si elle n'est pas là, il est là, et chargé.
Pour répondre À votre deuxième question:
Les ModulesPeuvent définir les noms qu'ils exporteront dans un scénario from camelot import *, et le comportement consiste à créer des noms pour les valeurs existantes, pas pour référencer des variables existantes (python n'a pas de références).
Sur un sujet quelque peu lié, faire un from camelot import * est pas la même chose qu'une importation régulière .