Ein persönlicher Hinweis zu Python-Importen. Wenn Sie Fehler oder andere Stolpersteine haben, kommentieren Sie bitte und PR.
Die Geschichte nach Python3.
Zum Beispiel
$ tree .
.
└── mypackage
├── __init__.py
├── mymodule1.py
└── mymodule2.py
Ich möchte mymodule1.py aus mymodule2.py importieren, wenn die Verzeichnisstruktur ist.
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))
Wann,
$ 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'
Wie in Python 2.7 kann mymodule1.py aus mymodule2.py importiert werden. Sie können sehen, dass es nicht in Python 3.5 importiert werden kann.
Importiere mymodule1
in mymodule2.py
Es ist beabsichtigt, mymodule1.py in derselben Hierarchie zu importieren (dies wird als impliziter relativer Import bezeichnet).
Wenn sich jedoch in sys.path
ein Paket mit demselben Namen befindet,
Versuchen Sie mypackage / mymodule1.py zu importieren?
Versuchen Sie, ein Paket namens mymodule auf sys.path zu importieren?
Es gibt ein Problem, das nicht unterschieden werden kann.
Daher wird in der Python3-Serie "import xxx" geändert, um das in "sys.path" vorhandene Paket zu importieren (als absoluter Import bezeichnet). Ein impliziter relativer Import ist nicht mehr möglich.
So importieren Sie die Module in das Paket Es muss klar angegeben werden, dass es sich um einen relativen Import handelt, z. B. "aus .import mymodule1" (dies wird als expliziter relativer Import bezeichnet).
https://www.python.org/dev/peps/pep-0328/#rationale-for-relative-imports
Nun, ich habe oben erwähnt, dass ich expliziten relavtiven Import verwende, um die Module in das Paket zu importieren. Es gibt Fälle, in denen der relative Import nicht verwendet werden kann, obwohl sich das Modul im Paket befindet. In diesem Fall lautet das Attribut "package" des Moduls im Paket "None" und das Attribut "name" "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()
Wenn Sie main.py ausführen
$ 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'
Wird angezeigt und Sie können sehen, dass mypackage / mymodule.py nicht importiert werden konnte.
Zu diesem Zeitpunkt ist das Attribut __package
von main.py None und das Attribut __name__
ist __main__
.
Es wird als Top-Level-Modul anerkannt.
Daher wird "." Von "von" zu "main.py" und "mymodule" kann nicht importiert werden.
Sei "von .import mymodule" "von mymodule import show".
Mit der Option -m
ausführen.
$ python3 -m mypackage.main
__package__: mypackage, __name__: __main__
A: 1000
Das Attribut "__package" ist "mypackage" und das Attribut "name" ist "main".
.
Of from .
zeigt auf dieselbe Hierarchie wie main.py,
Sie können mymodule.py mit from .import mymodule
importieren.
Die Ausführung von main.py durch -m
muss übrigens von außerhalb des Pakets erfolgen.
$ 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
Die Geschichte von Python 3.3 oder höher.
$ tree
.
├── mypackage1
│ ├── __init__.py
│ └── subdir1
│ ├── __init__.py.bak
│ └── mymodule1.py
└── mypackage2
└── subdir1
└── mymodule2.py
Wann,
$ 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__']
Sie können auch ohne "__init __. Py" importieren.
Normales Paket, mypackage1
mit __init __. Py
Mypackage2
without__init __. Py
wird als Namespace-Paket bezeichnet.
des Weiteren,
>>> 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'])
Als Paket, das zum selben Namespace gehört, auch wenn das Verzeichnis einen anderen Pfad, aber denselben Namen hat Im _NamespacePath-Objekt gespeichert.
Wenn import xxx
ausgeführt wird,
xxx / __ init __. Py
noch xxx. {Py, pyc, also}
in sys.path
vorhanden ist, aber ein Verzeichnis mit demselben Namen vorhanden ist, kann es als Namespace-Paket abgerufen werden.Der Unterschied ist
__path__
ist eine Liste, aber das Namespace-Paket__path__
ist ein _NamespacePath-Objekt.und so weiter.
Darüber hinaus wird ein Namespace-Paket erstellt (wobei "__init __. Py" entfernt wird).
>>> import subdir1.mymodule1
>>> import subdir1.mymodule2
>>> subdir1.mymodule1.__file__
'./mypackage1/subdir1/mymodule1.py'
>>> subdir1.mymodule2.__file__
'./mypackage2/subdir1/mymodule2.py'
Mit mymodule1.py
unter. / Mypackage1 / subdir1
, wie
Es kann separat von mymodule2.py
unter. / Mypackage2 / subdir1
importiert werden.
Ich kann mir keine Szene vorstellen, in der ich absichtlich das Namespace-Paket verwende.
Auch wenn Sie versehentlich __init __. Py
vergessen, können Sie es als Modul importieren.
In Anbetracht der Tatsache, dass der Initialisierungsprozess zum Zeitpunkt des Imports ausgeführt werden kann (z. B. Festlegen von "all"),
Wenn Sie keinen bestimmten Grund haben, ist es besser, "__init __. Py" zu setzen.
Weitere Informationen finden Sie unter PEP 420 - Implizite Namespace-Pakete.
PEP 420 -- Implicit Namespace Packages 24.07.2012 Ich habe das Python 3.3b1-Namespace-Paket ausprobiert
Recommended Posts