[Python] Der Stolperstein des Imports

Ein persönlicher Hinweis zu Python-Importen. Wenn Sie Fehler oder andere Stolpersteine haben, kommentieren Sie bitte und PR.

Der implizite relative Import kann nicht für den Import in Pakete verwendet werden

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.

Ursache

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.

Lösung

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).

Referenz-URL

https://www.python.org/dev/peps/pep-0328/#rationale-for-relative-imports

Wenn das Attribut "package" None und das Attribut "name" "main" ist, kann der relative Import nicht verwendet werden.

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.

Ursache

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.

Lösung 1

Sei "von .import mymodule" "von mymodule import show".

Lösung 2

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

Referenz-URL

https://www.python.org/dev/peps/pep-0328/#relative-imports-and-name

Sie können ein Paket ohne "__init __. Py" importieren

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.

Importauftrag

Wenn import xxx ausgeführt wird,

Unterschied zwischen regulärem Paket und Namespace-Paket

Der Unterschied ist

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.

Zusammenfassung

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.

Referenz-URL

PEP 420 -- Implicit Namespace Packages 24.07.2012 Ich habe das Python 3.3b1-Namespace-Paket ausprobiert

Recommended Posts

[Python] Der Stolperstein des Imports
der Zen von Python
Auf dem Weg zum Ruhestand von Python2
Über die Funktionen von Python
Die Kraft der Pandas: Python
Die Geschichte von Python und die Geschichte von NaN
Erster Python 3 ~ Der Beginn der Wiederholung ~
Anders als der Importtyp von Python. Bedeutung von aus A Import B.
Existenz aus Sicht von Python
pyenv-change die Python-Version von virtualenv
[Hinweis] Import von Dateien in das übergeordnete Verzeichnis in Python
[Python] Die potenzielle Feldplanung von Python Robotics verstehen
Überprüfung der Grundlagen von Python (FizzBuzz)
Informationen zur Grundlagenliste der Python-Grundlagen
26.11.2015 Python> Funktionsliste des Moduls anzeigen> Mathematik importieren> Verzeichnis (Mathematik)
Lernen Sie die Grundlagen von Python ① Grundlegende Anfänger
Ändern Sie die Länge der Python-CSV-Zeichenfolgen
Überprüfen Sie das Verhalten des Zerstörers in Python
[Python3] Verstehe die Grundlagen von Beautiful Soup
Übergeben Sie den Pfad des importierten Python-Moduls
Notizen vom Anfang von Python 1 lernen
Überprüfen Sie die Existenz der Datei mit Python
Informationen zur virtuellen Umgebung von Python Version 3.7
[Python3] Schreiben Sie das Codeobjekt der Funktion neu
Ich kannte die Grundlagen von Python nicht
Das Ergebnis der Installation von Python auf Anaconda
[Python] Probieren Sie pydash der Python-Version von lodash aus
[Python] Überprüfen Sie den Speicherverbrauch von Variablen
[Python] Importieren Sie das Modul eine Ebene höher
Überprüfen Sie den Pfad des importierten Python-Moduls
Die Geschichte der Manipulation globaler Python-Variablen
[Python] [Meta] Ist der Python-Typ ein Typ?
Grundlagen zum Ausführen von NoxPlayer in Python
Pandas des Anfängers, vom Anfänger, für den Anfänger [Python]
Die Python-Projektvorlage, an die ich denke.
Auf der Suche nach dem schnellsten FizzBuzz in Python
Python-Grundkurs (Ende 15)
Legen Sie den Prozessnamen des Python-Programms fest
[Python] Ruft den Zeichencode der Datei ab
Die Geschichte der Verarbeitung A von Blackjack (Python)
Lernen Sie intuitiv die Umformung von Python np
Python Hinweis: Die geheime Rolle von Kamma
Notizen vom Anfang von Python 2 lernen
Japanische Übersetzung: PEP 20 - Das Zen von Python
[Python3] Grundlegendes zu Dateivorgängen
Python-Modul importieren
Importieren Sie ein Python-Skript
Python-Grundlagen ①
Grundlagen von Python ①
Kopie von Python
Fassen Sie den Python-Import zusammen
Einführung von Python
Holen Sie sich den Inhalt von Git Diff aus Python
Geben Sie die Anzahl der CPU-Kerne in Python aus
[Python] Lesen Sie den Quellcode von Flasche Teil 2