Une note personnelle sur les importations Python. Si vous avez des erreurs ou d'autres obstacles, veuillez commenter et PR.
L'histoire après Python3.
Par exemple
$ tree .
.
└── mypackage
├── __init__.py
├── mymodule1.py
└── mymodule2.py
Je souhaite importer mymodule1.py depuis mymodule2.py lorsque la structure de répertoire est.
python:./mypackage/mymodule1.py
A = 1000
def show():
print('A: {}'.format(A))
python:./mypackage/mymodule2.py
import mymodule1
B = 100
def show():
print('A: {}, B: {}'.format(mymodule1.A, B))
Quand,
$ python2.7
Python 2.7.10 (default, Oct 23 2015, 19:19:21)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import mypackage.mymodule2 as mymod2
>>> mymod2.show()
A: 1000, B: 100
$ python3
Python 3.5.2 (default, Aug 4 2016, 09:38:15)
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import mypackage.mymodule2 as mymod2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/yusuke-nishioka/tests/tests1/mypackage/mymodule2.py", line 3, in <module>
import mymodule1
ImportError: No module named 'mymodule1'
Comme, dans Python 2.7, mymodule1.py peut être importé depuis mymodule2.py, Vous pouvez voir qu'il ne peut pas être importé dans Python 3.5.
ʻImport mymodule1dans mymodule2.py Il est prévu d'importer mymodule1.py dans la même hiérarchie (c'est ce qu'on appelle l'importation relative implicite). Cependant, s'il y a un paquet avec le même nom dans
sys.path`,
Essayez-vous d'importer mypackage / mymodule1.py?
Essayez-vous d'importer un package appelé mymodule sur sys.path?
Il y a un problème qui ne peut être distingué.
Par conséquent, dans la série Python3, ʻimport xxx est modifié pour importer le paquet existant dans
sys.path` (appelé importation absolue).
L'importation relative implicite n'est plus possible.
Pour importer les modules dans le package Il doit être clairement indiqué qu'il s'agit d'une importation relative, telle que «from .import mymodule1» (c'est ce qu'on appelle une importation relative explicite).
https://www.python.org/dev/peps/pep-0328/#rationale-for-relative-imports
Eh bien, j'ai mentionné ci-dessus que j'utilise une importation relavtive explicite pour importer les modules dans le package, Il y a des cas où l'importation relative ne peut pas être utilisée même si le module est dans le package. C'est à ce moment que l'attribut «package» du module dans le paquet est «None» et que l'attribut «name» est «main».
$ tree .
.
└── mypackage
├── __init__.py
├── main.py
└── mymodule.py
mypackge/mymodule.py
A = 1000
def show():
print('A: {}'.format(A))
mypackage/main.py
from . import mymodule
if __name__ == '__main__':
print('__package__: {}, __name__: {}'.format(
__package__, __name__))
mymodule.show()
Lorsque vous exécutez main.py
$ python3 mypackage/main.py
Traceback (most recent call last):
File "mypackage/main.py", line 1, in <module>
from . import mymodule
ImportError: cannot import name 'mymodule'
S'affiche et vous pouvez voir que mypackage / mymodule.py n'a pas pu être importé.
À ce stade, l'attribut __package
de main.py est None et l'attribut __name__
est __main__
.
Il est reconnu comme un module de premier niveau.
Par conséquent, .
of from .
devient main.py lui-même et mymodule
ne peut pas être importé.
Soit from .import mymodule
être from mymodule import show
.
Exécutez avec l'option -m
.
$ python3 -m mypackage.main
__package__: mypackage, __name__: __main__
A: 1000
L'attribut «__package» est «mypackage» et l'attribut «name» est «main».
.
Of from .
pointera vers la même hiérarchie que main.py,
Vous pouvez importer mymodule.py avec from .import mymodule
.
En passant, l'exécution de main.py par -m
doit être faite de l'extérieur du paquet.
$ cd mypackage
$ python3 -m main
Traceback (most recent call last):
File "/Users/yusuke-nishioka/.anyenv/envs/pyenv/versions/3.6.1/lib/python3.6/runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "/Users/yusuke-nishioka/.anyenv/envs/pyenv/versions/3.6.1/lib/python3.6/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/Users/yusuke-nishioka/Documents/United/tmp/mypackage/main.py", line 1, in <module>
from . import mymodule
ImportError: attempted relative import with no known parent package
https://www.python.org/dev/peps/pep-0328/#relative-imports-and-name
__init __. Py
L'histoire de Python 3.3 ou version ultérieure.
$ tree
.
├── mypackage1
│ ├── __init__.py
│ └── subdir1
│ ├── __init__.py.bak
│ └── mymodule1.py
└── mypackage2
└── subdir1
└── mymodule2.py
Quand,
$ python3
Python 3.5.2 (default, Aug 4 2016, 09:38:15)
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import mypackage1
>>> import mypackage2
>>> dir(mypackage1)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__']
>>> dir(mypackage2)
['__doc__', '__loader__', '__name__', '__package__', '__path__', '__spec__']
Comme, vous pouvez importer sans __init __. Py
.
Paquet régulier, mypackage1
avec __init __. Py
Mypackage2
sans__init __. Py
est appelé un package d'espace de noms.
plus loin,
>>> import sys
>>> sys.path.append('./mypackage1')
>>> sys.path.append('./mypackage2')
>>> import subdir1
>>> dir(subdir1)
['__doc__', '__loader__', '__name__', '__package__', '__path__', '__spec__']
>>> subdir1.__path__
_NamespacePath(['./mypackage1/subdir1', './mypackage2/subdir1'])
En tant que package qui appartient au même espace de noms même si le répertoire a un chemin différent mais le même nom Stocké dans l'objet _NamespacePath.
Lorsque ʻimport xxx` est exécuté,
xxx / __ init __. Py
existe dans sys.path
, il peut être obtenu sous forme de paquetage normal.xxx / __ init __. Py
n'existe pas dans sys.path
mais quexxx. {Py, pyc, so}
existe, il peut être obtenu en tant que module.xxx / __ init __. Py
ni xxx. {Py, pyc, so} ʻexiste dans
sys.path` mais qu'un répertoire avec le même nom existe, il peut être obtenu comme un package d'espace de noms.La différence est
__file__
__path__
est une liste, mais le package d'espace de noms__path__
est un objet _NamespacePath.etc.
De plus, en en faisant un package d'espace de noms (en éliminant __init __. Py
)
>>> import subdir1.mymodule1
>>> import subdir1.mymodule2
>>> subdir1.mymodule1.__file__
'./mypackage1/subdir1/mymodule1.py'
>>> subdir1.mymodule2.__file__
'./mypackage2/subdir1/mymodule2.py'
Avec mymodule1.py
under. / Mypackage1 / subdir1
, comme
Il peut être importé séparément de mymodule2.py
sous. / Mypackage2 / subdir1
.
Je ne peux pas penser à une scène où j'utilise intentionnellement le package d'espace de noms,
Même si vous oubliez par inadvertance __init __. Py
, vous pouvez l'importer en tant que module.
Cependant, considérant que le processus d'initialisation peut être exécuté au moment de l'importation (comme par exemple en définissant __all__
),
Sauf si vous avez une raison spécifique, il semble préférable de mettre __init __. Py
.
Voir PEP 420 - Packages d'espaces de noms implicites pour plus d'informations.
PEP 420 -- Implicit Namespace Packages 2012/07/24 J'ai essayé le package d'espace de noms Python 3.3b1
Recommended Posts