Avant-propos
Il existe deux façons d'organiser les modules en python, l'une est un simple fichier python, le nom du fichier est le nom du module, l'autre est un package, un package est un répertoire contenant plusieurs fichiers python . Il doit y avoir un fichier __init__.py dans le répertoire, donc le nom du répertoire est le nom du module. Les fichiers python du package peuvent également être importés via la syntaxe nom du package.file name import
import. 🎜>
Il existe deux types de syntaxe d'importation
1 Importer directement des modules
import Module
import Module as xx
Copier après la connexion
2. , classes, fonctions, variables, etc.)
from Module import Name
from Module immport Name as yy
Copier après la connexion
car la syntaxe est utilisée pour définir l'alias d'un objet (l'objet fait ici référence aux modules, classes, fonctions, etc.) , et import introduit le nom de l'objet dans l'espace de noms du fichier actuel
Supposons qu'il existe la structure de répertoires suivante
├── A.py
└── pkg
├── B.py
└── __init__.py
Copier après la connexion
Dans le répertoire actuel, le suivant les déclarations sont valides
import A
import pkg
import pkg.B
from pkg import B
Copier après la connexion
Afin de simplifier la discussion, il n'y aura pas d'exemples de syntaxe ci-dessous
étapes d'importation
Toutes les informations du module chargé en python sont stockées dans la structure sys.modules Lors de l'importation d'un module, procédera comme suit
S'il s'agit de l'importation A, vérifiez s'il y a déjà A dans sys.modules, s'il y en a. c'est-à-dire qu'il ne sera pas chargé, sinon, créez un objet module pour A, et chargez A
S'il provient de A, importez B, créez d'abord un objet module pour A, puis analysez A, recherchez B à partir de et remplissez-le dans le __dict__
Importation imbriquée
Lors de l'importation d'un module, nous pouvons nous demander si un module sera importé plusieurs fois. Supposons qu'il y ait trois modules. A, B et C. A doit importer B et C, et B doit importer C. De cette façon, A exécutera Import C deux fois, une fois par lui-même et une fois par lui-même lors de l'importation de B. Cependant, selon le étapes d'importation mentionnées ci-dessus, il a été constaté que le module a été chargé lors de la deuxième importation, donc l'importation ne sera pas répétée
Mais une erreur sera signalée dans la situation suivante
#filename: A.py
from B import BB
class AA:pass
#filename: B.py
from A import AA
class BB:pass
Copier après la connexion
À ce moment-là, que A.py ou B.py soit exécuté, une exception ImportError sera levée. Supposons que nous exécutons A. py, la raison est la suivante
Quand. le fichier A.py s'exécute à partir de B import BB, B.py sera analysé en premier et un objet module sera créé pour B dans l'espace de noms de A, en essayant de trouver BB à partir de B
Scannez la première ligne de B.py et exécuté à partir de A import AA À ce moment, il analysera A.py
Scanner la première ligne de A.py et exécuter à partir de B import BB Puisque l'étape 1 est déjà B crée un. objet module, il obtiendra donc BB directement à partir du __dict__ de l'objet module de B. Évidemment, BB ne peut pas être obtenu pour le moment, donc une exception est levée
Il existe deux façons de résoudre cette situation. Dans un sens,
passez de B import BB à import B, ou passez de A import AA à import A
Échangez les deux lignes de code dans A.py ou B.py
En bref, ce à quoi vous devez faire attention lors de l'importation, c'est d'essayer d'importer
package import
quand il y a __init__ dans un répertoire. fichier, le répertoire est un package python
L'importation d'un package revient à importer un seul fichier. Nous pouvons faire une analogie comme celle-ci :
Lors de l'importation d'un seul fichier, les classes et les fonctions. dans le fichier, les variables peuvent être utilisées comme objets d'importation
Lors de l'importation d'un package, les sous-packages, les fichiers du package, ainsi que les classes, fonctions et variables dans __init__.py peuvent être utilisés comme objets d'importation
Supposons qu'il existe la structure de répertoires suivante
pkg
├── __init__.py
└── file.py
Copier après la connexion
Le contenu de __init__.py est le suivant
argument = 0
class A:pass
Copier après la connexion
Exécuté dans le même répertoire que pkg Les déclarations suivantes sont OK
>>> import pkg
>>> import pkg.file
>>> from pkg import file
>>> from pkg import A
>>> from pkg import argument
Copier après la connexion
mais les déclarations suivantes sont fausses
>>> import pkg.A
>>> import pkg.argument
Copier après la connexion
ImportError : Aucun module nommé xxx, car lorsque nous exécutons l'import A.B, A et B doivent être des modules (fichiers ou packages)
Import relatif et import absolu
Le format de l'absolu import est import A.B ou from A import B, le format d'importation relatif est from .import B ou from ..A import B, .. représente le module de niveau supérieur, ... représente le niveau supérieur. module, et ainsi de suite. Lorsque nous avons plusieurs packages, il peut être nécessaire d'importer le contenu d'un package dans un autre, ce qui entraînera une importation absolue, et c'est souvent à ce moment-là que des erreurs sont les plus susceptibles de se produire. Permettez-moi d'illustrer avec un exemple spécifique<🎜. >
La structure des répertoires est la suivante
app
├── __inti__.py
├── mod1
│ ├── file1.py
│ └── __init__.py
├── mod2
│ ├── file2.py
│ └── __init__.py
└── start.py
Copier après la connexion
Le contenu de app/start.py est import mod1.file1
app/mod1 /file1.py content Pour from ..mod2 import file2
Afin de faciliter l'analyse, nous ajoutons print __file__, __name__
à la première ligne de tous les fichiers py (y compris __init__.py) maintenant app/mod1/file1. L'importation relative est utilisée dans py. Lorsque nous exécutons python file1.py sous app/mod1 ou exécutons python mod1/file1.py sous app, l'erreur ValueError : tentative d'importation relative dans un non-package
.
sera signalé lors de l'exécution sous app. python -m mod1.file1 ou python start.py signalera une erreur ValueError : tentative d'importation relative au-delà du package de niveau supérieur
Les raisons spécifiques seront discutées plus tard. regardez quelques règles lors de l'importation de modules
Lorsque la structure du package n'est pas explicitement spécifiée, python détermine la structure d'un module dans le package en fonction de __name__ S'il s'agit de __main__, c'est le module de niveau supérieur lui-même et. n'a pas de structure de package. S'il s'agit de la structure A.B.C, alors le module de niveau supérieur est A.
Suivez essentiellement ce principe
S'il s'agit d'une importation absolue, un module ne peut importer que ses propres sous-modules ou modules et sous-modules au même niveau que son module de niveau supérieur
S'il s'agit d'une importation relative, un module doit avoir une structure de package et ne peut importer des modules qu'à l'intérieur de son module de niveau supérieur
La structure des répertoires est la suivante
A
├── B1
│ ├── C1
│ │ └── file.py
│ └── C2
└── B2
Copier après la connexion
其中A,B1,B2,C1,C2都为包,这里为了展示简单没有列出__init__.py文件,当file.py的包结构为A.B1.C1.file(注意,是根据__name__来的,而不是磁盘的目录结构,在不同目录下执行file.py时对应的包目录结构都是不一样的)时,在file.py中可采用如下的绝对的导入
import A.B1.C2
import A.B2
Copier après la connexion
和如下的相对导入
from .. import C2
from ... import B2
Copier après la connexion
什么情况下会让file.py的包结构为A.B1.C1.file呢,有如下两种
在A的上层目录执行python -m A.B1.C1.file, 此时明确指定了包结构
在A的上层目录建立文件start.py,在start.py里有import A.B1.C1.file,然后执行python start.py,此时包结构是根据file.py的__name__变量来的
再看前面出错的两种情况,第一种执行python file1.py和python mod1/file1.py,此时file.py的__name__为__main__ ,也就是说它本身就是顶层模块,并没有包结构,所以会报错
第二种情况,在执行python -m mod1.file1和python start.py时,前者明确告诉解释器mod1是顶层模块,后者需要导入file1,而file1.py的__name__为mod1.file1,顶层模块为也mod1,所以在file1.py中执行from ..mod2 import file2时会报错 ,因为mod2并不在顶层模块mod1内部。通过错误堆栈可以看出,并不是在start.py中绝对导入时报错,而是在file1.py中相对导入报的错
那么如何才能偶正确执行呢,有两种方法,一种是在app上层目录执行python -m app.mod1.file1,另一种是改变目录结构,将所有包放在一个大包中,如下
app
├── pkg
│ ├── __init__.py
│ ├── mod1
│ │ ├── __init__.py
│ │ └── file1.py
│ └── mod2
│ ├── __init__.py
│ └── file2.py
└── start.py
Copier après la connexion
start.py内容改成import pkg.mod1.file1,然后在app下执行python start.py
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家学习或者使用python能带来一定的帮助,如有疑问大家可以留言交流。
更多python中import学习备忘笔记相关文章请关注PHP中文网!