En fait, le comportement de l' __import__()
est entièrement à cause de la mise en œuvre de l' import
déclaration, qui demande __import__()
. Il y a principalement cinq légèrement différentes façons __import__()
peut être appelé en import
(avec deux catégories principales):
import pkg
import pkg.mod
from pkg import mod, mod2
from pkg.mod import func, func2
from pkg.mod import submod
Dans le premier et le second cas, l' import
déclaration doit attribuer le "plus à gauche" module objet de la "plus à gauche" nom: pkg
. Après l' import pkg.mod
que vous pouvez faire pkg.mod.func()
parce que l' import
déclaration introduit le nom local pkg
, ce qui est un module objet qui a un mod
d'attribut. Ainsi, l' __import__()
de la fonction doit retourner le "plus à gauche" module objet de sorte qu'il peut être assigné à l' pkg
. Ces deux déclarations d'importation se traduisent donc par:
pkg = __import__('pkg')
pkg = __import__('pkg.mod')
Dans les troisième, quatrième et cinquième cas, l' import
déclaration a faire plus de travail: il a affecter (potentiellement) plusieurs noms, dont il a fait obtenir à partir de l'objet module. L' __import__()
fonction ne peut retourner un objet, et il n'y a pas vraiment de raison de le faire récupérer chacun de ces noms de l'objet module (et ça ferait de la mise en œuvre beaucoup plus complexe.) Donc, l'approche la plus simple serait quelque chose comme (pour le troisième cas):
tmp = __import__('pkg')
mod = tmp.mod
mod2 = tmp.mod2
Toutefois, cela ne fonctionnera pas si pkg
est un package et mod
ou mod2
sont des modules dans le paquet qui ne sont pas déjà importés, comme ils le sont dans le troisième et le cinquième cas. L' __import__()
fonction a besoin de savoir qu' mod
et mod2
sont des noms que l' import
déclaration voulez avoir accès, et donc qu'il peut voir si elles sont des modules et d'essayer de les importer. Donc, l'appel est plus proche de:
tmp = __import__('pkg', fromlist=['mod', 'mod2'])
mod = tmp.mod
mod2 = tmp.mod2
ce qui provoque __import__()
de l'essayer et de la charge pkg.mod
et pkg.mod2
ainsi que pkg
(mais si mod
ou mod2
n'existe pas, ce n'est pas une erreur dans l' __import__()
appel; produire une erreur est laissé à l' import
sur le relevé). Mais ce n'est toujours pas la bonne chose pour les quatrième et cinquième exemple, parce que si l'appel étaient donc:
tmp = __import__('pkg.mod', fromlist=['submod'])
submod = tmp.submod
ensuite, tmp
est pkg
, comme avant, et non pas l' pkg.mod
module que vous souhaitez obtenir de l' submod
attribut. La mise en œuvre pourrait avoir décidé de faire ainsi l' import
déclaration de travaux supplémentaires, le fractionnement du nom de package sur .
comme l' __import__()
fonction déjà fait et traversant les noms, mais cela aurait signifié dupliquer les efforts. Donc, au lieu de cela, la mise en œuvre fait __import__()
de retour le plus à droite du module au lieu de la plus à gauche d'un si et seulement si fromlist est passée et pas vide.
( import pkg as p
Et from pkg import mod as m
de la syntaxe ne change rien à cette histoire, à l'exception de ce qui les noms locaux affectés à -- l' __import__()
fonction ne voit rien de différent lors de l' as
est utilisé, tout cela reste dans l' import
déclaration de mise en œuvre.)