Erhalten Sie ein abstraktes Verständnis der Python-Module und -Pakete

Einführung

Informationen zum Python-Importsystem

Sie können das verstehen, Wenn Sie sich von physischen Dateien entfernen und etwas abstrakter denken, wird die Sichtbarkeit des gesamten Systems, wie z. B. Modulnamen, relative Importe, Initialisierungszeitpunkt und Sichtbarkeit der Namen, verbessert.

Beachten Sie, dass dieser Artikel keine ** Namespace-Pakete [^ 1] ** behandelt (weil ich sie nicht verstehe).

Verweise

Ich habe die Version 3.8.2 von beiden durchsucht.

Umgebung

Bestätigt für die Arbeit mit Python v3.8.2. Überprüfen Sie den Vorgang als Testfall für Pytest.

pip install pytest

Im Anhang finden Sie Informationen zur Funktionsweise des Pytests.

Überblick

Eine kurze Zusammenfassung der Attribute:

__name__ __path__ __package__
Modul: Modul名 Keiner Name des übergeordneten Pakets
Paket: Paket名 Paketのパス Paket名

Was ist ein Namespace?

Dies ist ein in Programmiersprachen häufig verwendetes Konzept ** Dies ist eine Funktion, mit der Sie "Namen" wie den Variablennamen "x" an verschiedenen Stellen im Programm mit unterschiedlichen Bedeutungen verwenden können, ohne Kollisionsangst zu befürchten. ** ** ** Zum Beispiel sind builtins.open und os.open beide Funktionsnamen, aber weil sie zu verschiedenen Namespaces gehören, Kann als unterschiedlich definiert und verwendet werden. Das unten beschriebene "Modul" ist diese ** Namespace-Einheit **.

In der Python-Dokumentation befindet sich ein Glossar mit einem "Namespace" -Eintrag: https://docs.python.org/ja/3/glossary.html#term-namespace

Was ist ein Modul? Was ist ein Import?

Wie in der Übersicht erwähnt, ist ein Modul eine ** Namespace-Einheit, die importiert werden kann **.

Namespace-Einheit

Erstens, weil ein Modul eine Einheit des Namespace ist, für die Module m und n der Name in m`` x (= mx) und der Name in n`` x (= nx ) Wird unterschieden.

Der gesamte Code funktioniert in einem bestimmten Namespace

Zweitens wird der gesamte Code weniger bewusst in einem Modul ausgeführt, dh in einem Namespace. Wenn der Code einen Namen deklariert und definiert, wird er in diesem Namespace registriert. Unmittelbar nach dem Start des Python-Interpreters wird der Code im ** __ main__ Modul-Namespace ** ausgeführt. Dies wird häufig verwendet, um festzustellen, ob eine .py-Datei direkt gestartet oder importiert wurde.

Modulimport

Das Modul kann dann importiert werden. Ein Modul importieren bedeutet

--Finden und zwischenspeichern Sie das Modul und --Laden und initialisieren,

Das ist. Das Dokument enthält 2 Schritte. Wenn Sie es jedoch als 3 Schritte betrachten, ist die Verarbeitungseinheit leicht zu verstehen. Einfach ausgedrückt, indem Sie das Modul m als import m importieren

--Suchen Sie nach dem Modul m in sys.path und registrieren Sie das Modulobjekt im globalen Cache sys.modules.

Starten Sie den Python-Interpreter im interaktiven Modus und checken Sie ihn aus. (Teilweise zur besseren Lesbarkeit geformt)

[.../module-experiments]$ python
Python 3.8.2 (default, Apr 18 2020, 18:08:23) 
[Clang 10.0.1 (clang-1001.0.46.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

>>> print(__name__)
__main__

>>> import m
>>> sys.modules['m']
<module 'm' from '.../module-experiments/m.py'>
>>> m
<module 'm' from '.../module-experiments/m.py'>
>>> m.f
<function f at 0x108452b80>
>>> m.C
<class 'm.C'>

Sie können sehen, dass das Modul unmittelbar nach dem Start "main" ist. Sie können auch sehen, dass Sie durch Importieren von m auf m, m.f und m.C zugreifen können.

Das importierte Modul wird im lokalen Namespace zwischengespeichert. Daher kann wie bei jedem anderen Namen auf ein in eine Funktion importiertes Modul nicht von anderen Funktionen zugegriffen werden. Da der Cache jedoch global ist, kann auf ihn zugegriffen werden.

Was ist ein Paket?

Ein Paket ist wie ein Modul, nur dass Sie darin nach Submodulen suchen und diese importieren können. Mithilfe von Paketen können Sie eine hierarchische Struktur von Modulen erstellen.

Einfach ausgedrückt

Der Name des Moduls (oder Pakets) ist dann so etwas wie "a.b.c", getrennt durch Punkte. Durch Importieren des Moduls a.b.c mit importieren a.b.c

Auf diese Weise können Sie mit "a.b.c" auf das Modul "a.b.c" zugreifen. ** Hinweis: Sie können mit c nicht darauf zugreifen. ** ** **

Diese Regel zeigt auch, dass Pakete und Module auf die gleiche Weise importiert werden können.

Natürlich können Sie nicht sofort nach dem Importieren von "a.b.c" auf "a.d" oder "a.d.e" zugreifen. Wenn Sie hier "a.d.e importieren", ist "a" im Cache vorhanden

--Importieren Sie das Submodul (Paket) d ( a.d) in den Namespace des Moduls a

Kommt nur vor, also wird an diesen Stellen das Modul initialisiert.

Ein bisschen mehr Detail

Technisch gesehen ist ein Paket ein Modul mit dem Attribut __path__. Dieses Attribut wird bei der Suche nach Unterpaketen verwendet. Mit anderen Worten, in "import a.b.c",

--Finden und importieren Sie "a" aus "sys.path" --Finden und importieren Sie "a.b" von "a .__ path__" im Namespace des Moduls "a" --Finden und importieren Sie "a.b.c" aus "a.b.__ path__" im Namespace des Moduls "a.b"

Das passiert gerade.

Das Modul, das das Paket enthält, hat das Attribut __name__. Bei importierten Modulen ist dieser Wert der vollständig qualifizierte Name des Moduls (z. B. "a.b.c").

Paketimport

Da ein Paket ein Modul ist, kann es mit der import-Anweisung wie ein Modul importiert werden.

import ... as ...

Wenn die import-Anweisung eine "as" -Klausel enthält, ist das importierte Modul selbst an einen Namen gebunden, der kleiner oder gleich "as" ist. Mit "a.b als b importieren" können Sie beispielsweise direkt mit dem Namen "b" auf das Modul "a.b" zugreifen.

Zu diesem Zeitpunkt werden, da das Modul "a" geladen und initialisiert ist, die Informationen über das Modul "a" (und natürlich "a.b") zwischengespeichert. A ist jedoch nicht an den Namespace gebunden.

>>> import sys
>>> import a.b as b
['/Users/shinsa/git/python-experiments/module-experiments/a']
a

>>> sys.modules['a']
<module 'a' from '/Users/shinsa/git/python-experiments/module-experiments/a/__init__.py'>
>>> sys.modules['a.b']
<module 'a.b' from '/Users/shinsa/git/python-experiments/module-experiments/a/b/__init__.py'>

>>> b
<module 'a.b' from '/Users/shinsa/git/python-experiments/module-experiments/a/b/__init__.py'>

>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined

Modulname und Name sind unterschiedlich

Der Modulname kommt unmittelbar nach "Import" und Sie können den definierten Namen an dieser Stelle nicht verwenden. Daher können Sie "import a.b.c" nicht als "import b.c" schreiben, nur weil Sie "import a.b as b" sagen.

Importieren mit from Klausel

Diese Form des Imports ist der Fall von "from a.b import c". c kann ein Modul, ein Paket oder ein Name sein. Die folgende Verarbeitung wird durchgeführt.

--Import a.b. Der Name ist jedoch nicht gebunden.

Wenn die "as" -Klausel angegeben ist, ist sie anstelle der Bindung von "c" im obigen Beispiel an den in der "as" -Klausel angegebenen Namen gebunden.

from ... import *

Wenn der zu importierende Name "*" ist, dh "von M import *", dann im Modul "M"

Sind alle im aktuellen Namespace gebunden.

Relativer Import

In der Anweisung "from ... import ..." können Sie relative Paketdarstellungen in der Klausel "from" verwenden. Zum Beispiel im Initialisierungsskript für das Paket "a.b" oder im Skript für das Modul "a.b.c"

Vertreten Sie jeden. Sie können mehr Punkte haben.

PEP 366

Relative Paketberechnungen basierten auf dem Attribut __name__. Wenn Sie beispielsweise den Interpreter mit "python -m a.b.c" starten, fungiert "a / b / c.py" als "main" -Modul. Aus diesem Grund gab es ein Problem, dass beispielsweise "a.b.d" nicht relativ importiert werden konnte.

In neueren Versionen von Python werden relative Importe jetzt basierend auf dem Attribut "package" berechnet, wodurch das oben genannte Problem mit der Anrufzeit (PEP 366) behoben wird. Wenn Sie es jedoch mit python <Pfad> / a / b / c.py starten, müssen Sie die Attribute manuell festlegen.

Standardimplementierung: System für Dateisystem importieren

Bisher haben wir abstrakt über Module, Pakete und path gesprochen. Mit anderen Worten, ich spreche überhaupt nicht über ein bestimmtes Dateisystem. In neueren Versionen ist das Importsystem von Python zu einem sehr abstrakten und leistungsstarken System geworden.

Standardmäßig arbeitet das Importsystem mit einem Dateisystem. Standardmäßig werden Module durch ".py" -Dateien und Pakete durch Verzeichnisse dargestellt. Die Details sind wie folgt und es ist ersichtlich, dass sie bisher zur abstrakten Datenstruktur passen.

Umgekehrt kann beispielsweise ein URI-basiertes Importsystem implementiert werden, und der Diensterkennungsmechanismus kann unter Verwendung des Python-Importsystems implementiert werden.

Endlich: Ein bisschen unzufrieden

Die Python-Dokumentation ist verwirrend, da die Informationen überall verteilt sind. Es ist immer noch verständlich, wenn Sie dies tun, um doppelte Informationen zu vermeiden. Stattdessen wird jede Information subtil dupliziert, aber verstreut. Darüber hinaus sind einige Informationen veraltet.

Recommended Posts

Erhalten Sie ein abstraktes Verständnis der Python-Module und -Pakete
Python-Pakete und -Module
Lernen Sie Python-Pakete und -Module kennen
Python-Grundkurs (14 Module und Pakete)
Module und Pakete in Python sind "Namespaces"
Vollständiges Verständnis von Python-Threading und Multiprocessing
Organisieren Sie Python-Module und -Pakete in einem Chaos
[Python] Ein grobes Verständnis von Iterablen, Iteratoren und Generatoren
Liste der Python-Module
Asynchrone Verarbeitung von Python ~ Asynchron vollständig verstehen und warten ~
Python: Ruft eine Liste der Methoden für ein Objekt ab
[Python] Quotient und Überschuss erhalten
Quellinstallation und Installation von Python
Vollständiges Verständnis des Python-Debuggens
Befreien Sie sich mit Python und regulären Ausdrücken von schmutzigen Daten
Beispiel für das Parsen von HTTP GET und JSON mit Pfefferpython
Umgebungskonstruktion von Python und OpenCV
Die Geschichte von Python und die Geschichte von NaN
Pakete, die MIDI mit Python Midi und Pretty_Midi verarbeiten
Multiprocessing Memorandum
Sofortige Mehrfachverarbeitung
Vollständiges Verständnis von Python-Threading und Multiprocessing
Installation von SciPy und matplotlib (Python)
Hinweis: Holen Sie sich das erste und letzte Element von Python OrderedDict zerstörungsfrei
Python und DB: DBI-Cursor verstehen
So verwenden Sie das Python-Visualisierungspaket ordnungsgemäß
[Python] So erhalten Sie den ersten und den letzten Tag des Monats
Ruft die Attribute eines Objekts ab
Dies und das von Python-Eigenschaften
[Python] Die potenzielle Feldplanung von Python Robotics verstehen
Rufen Sie den Wert des Dropdown-Menüs mit Python und Selen ab und legen Sie ihn fest
Koexistenz von Python2 und 3 mit CircleCI (1.0)
Zusammenfassung der Python-Indizes und -Slices
Holen Sie sich den Titel und das Lieferdatum von Yahoo! News in Python
Reputation von Python-Büchern und Nachschlagewerken
Holen Sie sich Bilder von OpenStreetMap und Geographical Institute Map mit Python + py-staticmaps
Rufen Sie mit Python eine Liste der in der aktuellen Umgebung installierten Pakete ab
Ein leicht verständlicher Vergleich der grundlegenden Grammatik von Python und Go
Öffnen Sie eine Excel-Datei in Python und färben Sie die Karte von Japan
Holen Sie sich Artikelbesuche und Likes mit Qiita API + Python
Holen Sie sich Bilder von OpenStreetMap und Geographical Institute Map mit Python + staticmap
Erhalten und schätzen Sie die Form des Kopfes mit Dlib und OpenCV mit Python
Ruft den Rückgabewert eines externen Shell-Skripts (ls) mit python3 ab
Erläuterung zum Erstellen einer Anwendung zum Anzeigen von Bildern und Zeichnen mit Python
Installation von Visual Studio Code und Installation von Python
Ein grobes Verständnis von Python-Feuer und ein Memo
Virtuelle Python-Umgebung und Pakete unter Ubuntu
Extraktion von tweet.js (json.loads und eval) (Python)
[Python] Packen und verteilen Sie Ihre eigenen Module
Verbinde viel Python oder und und
[Python] Ruft eine Liste der Instanzvariablen ab
(Hinweis) Massenaktualisierung von in Python installierten Paketen
Zusammenfassung der Module und Klassen in Python-TensorFlow2-
[Python] Ruft den Zeichencode der Datei ab
Einfache Einführung in die Python3-Serie und OpenCV3
[Python] Verschiedene Kombinationen von Zeichenketten und Werten
[Python] Nur eine Liste der Ordner abrufen
Gleiche Automatisierung des Python- und PyPI-Setups
Entfernen Sie DICOM-Bilder in Python
Projekt Euler # 1 "Vielfaches von 3 und 5" in Python
Python3> Anweisung übergeben> kleinste Klasse / Inhalt von Funktionen und Bedingungen erstellen> beim Denken auf abstrakter Ebene
Holen Sie sich mit Python den Aktienkurs eines japanischen Unternehmens und erstellen Sie eine Grafik