Lernen Sie Python-Pakete und -Module kennen

Einführung

Wenn Sie Python berühren, können Sie den Unterschied zwischen einem Modul und einem Paket nicht wirklich erkennen. Besonders wenn eine IDE namens PyCharm verwendet wird, verhält sie sich seltsam.

Daher möchte ich den Kampf zwischen dem Paket und dem Modul zusammenfassen, damit ich später darauf zurückblicken kann.

Berühren Sie das Modul

Berühren wir zuerst das Modul.

Was ist ein Modul?

Module repräsentieren "Dateien" in Python. Mit anderen Worten, wenn Sie eine Datei mit dem Namen "add.py" erstellen, handelt es sich um ein Modul mit dem Namen "add".

Durch die Trennung der Funktionen für jedes Modul kann vermieden werden, dass die Funktionen in eine einzelne Datei umgewandelt werden.

Verzeichnis

Derzeit verwenden wir eine solche Verzeichnisstruktur.

In einem Verzeichnis namens Python_Tutorial Enthält Folgendes:

.
├── __pycache__
├── calc
│   ├── add.py
│   ├── calc_main.py
│   ├── mul.py
│   └── sub.py
└── main.py

Schreiben Sie das Modul in das Verzeichnis calc Versuchen Sie dann, ein anderes Rechenmodul von calc_main aus aufzurufen. Versuchen Sie danach, main.py direkt unter Python_Tutorial zu verwenden.

Vorbereitung

add.py, mul.py, sub.py Bereiten.

print('add.py')
print(__name__)


def add(x, y):
    return x + y


if __name__ == '__main__':
    print(add(10, 20))
print('sub.py')
print(__name__)


def sub(x, y):
    return x - y


if __name__ == '__main__':
    print(sub(10, 20))

print('mul.py')
print(__name__)


def mul(x, y):
    return x * y


if __name__ == '__main__':
    print(mul(10, 20))

Was ist name

mit add.py etc.

if __name__ == '__main__':
    print(mul(10, 20))

Ist beigefügt, aber was ist das?

Es enthält den "Namen, als die Datei $ f $ .py ausgeführt wurde".

Versuchen Sie beispielsweise, add.py auszuführen. dann,

add.py
__main__
30

Wird ausgegeben.

Dies liegt daran, dass es ausgehend von der Datei $ f $ = add ausgeführt wird und main in name der ausführbaren Datei festgelegt ist.

Beachten Sie, dass name in der Ausführungsursprungsdatei immer main ist.

Versuchen Sie, das Modul aufzurufen

Versuchen Sie, add, sub, mul im selben Verzeichnis wie calc_main.py auszuführen.

calc_main.py



import add

'''
add.py
add
30
'''
print(add.add(10, 20))

from sub import sub

'''
sub.py
sub
-10
'''
print(sub(20, 30))


from mul import *

'''
mul.py
mul
1500
'''
print(mul(30, 50))

Anscheinend

Importieren Sie den Dateinamen in dieselbe Hierarchie

Es scheint also, dass andere Dateien als Module gelesen werden können.

Laden hinzufügen

import add

Wenn Sie dies tun, werden zwei Ausdrucke von add.py ausgeführt. Daher scheint es, dass eine solide Schreibverarbeitung wie Drucken ausgeführt wird, wenn das Modul geladen wird. Außerdem enthält name add. Auf diese Weise scheint der Dateiname so eingegeben zu werden, wie er ist, wenn er als Modul anstelle des Ausführungsstartpunkts aufgerufen wird.

Dateiname importieren Da es eingelesen ist, kann die Funktion in add.add verwendet werden, dem Namespace des Dateinamens.

Diese Notation scheint sicher zu sein, da die Funktion "Hinzufügen" die Namespaces des anderen schützt, selbst wenn sie sich in anderen Dateien befinden!

Unter lesen

from sub import sub

Wenn Sie dies tun, scheinen Sie die Unterfunktion von sub.py direkt zu lesen. Es scheint möglich zu sein, es aus dem Modul zu entfernen.

Es scheint jedoch, dass die Unterfunktion nicht direkt abgerufen werden kann. Wie add.py

'''
sub.py
sub
'''

Wird ausgegeben, so scheint es, dass der gesamte Inhalt der Subdatei zum Zeitpunkt von from sub ausgeführt wird.

Laden von Mul

from mul import *

Sie können den gesamten Inhalt der Mul-Datei in großen Mengen in den Namespace calc_main.py erzwingen.

Grundsätzlich ** scheint es besser, nicht zu verwenden **. Der Grund dafür ist, dass es zu unerwartetem Verhalten kommt, z. B. zum Überschreiben, wenn derselbe Name wie bei anderen Modulen verwendet wird.

Lesen Sie die Zusammenfassung im selben Verzeichnis

Dateiname importieren

Kann am bequemsten sein.

Versuchen Sie es mit mehreren Lesungen

Versuchen Sie als nächstes das mehrfache Laden. Ich bin ein Baum, wie es sich verhält, wenn dieselbe Datei oft gelesen wird

Verzeichnisaufbau

Um zu versuchen, mehrere zu laden a b Eine einfache Konfiguration wie c scheint einfacher zu sein.

Versuche Folgendes.

.
├── __pycache__
├── abc
│   ├── a.py
│   ├── ab.py
│   ├── abc_main.py
│   ├── b.py
│   ├── bc.py
│   ├── c.py
│   └── ca.py
├── calc
│   ├── __pycache__
│   │   ├── add.cpython-37.pyc
│   │   ├── mul.cpython-37.pyc
│   │   └── sub.cpython-37.pyc
│   ├── add.py
│   ├── calc_main.py
│   ├── mul.py
│   └── sub.py
├── main.py

Abc-Verzeichnis hinzugefügt. ab.py liest a- und b-Dateien als Module.

Vorbereitung

print('a file')

aa = 1
print('b file')

bb = 2
print('c file')

cc = 3

Das Experiment beginnt mit a, b und c.py wie oben beschrieben.

Vorbereitung 2

Versuchen Sie, die entsprechenden Dateien aus der Datei ab.py usw. zu lesen.

ab.py


import a
import b


print('ab file')

bc.py


import b
import c

print('bc file')

ca.py


import c
import a

print('ca file')

abc_main.py


import ab
import bc
import ca

print('abc main file')

abc_main.py

Wenn ich abc_main.py starte, sieht es so aus:

a file
b file
ab file
c file
bc file
ca file
abc main file

Es scheint, dass die Dateien a und b zuerst gelesen werden. Danach sollten B- und C-Dateien als B-Datei ausgegeben, aber übersprungen und als C-Datei ausgegeben werden.

Anscheinend wird es nicht geladen, sobald es geladen ist.

Das Lesen der ca-Datei scheint nicht zu ärgern, da die c- und a-Dateien bereits gelesen wurden. Mit Ausnahme der Tatsache, dass "eine Datei" usw., wenn sie einmal gelesen wird, danach nicht mehr gelesen und nur einmal ausgegeben wird.

Anscheinend wird die Datei grundsätzlich nur einmal gelesen. ``

Versuchen Sie, das Modul eine Ebene tiefer zu verwenden

Derzeit habe ich Module im selben Verzeichnis wie abc_main und calc_main verwendet.

Ist es dann möglich, ein Modul im nächstniedrigeren Verzeichnis wie main.py zu verwenden?

main.py

main.py


from calc import add

'''
add.py
calc.add
5
'''
print(add.add(2, 3))

Wie oben erwähnt, wird das Add-Modul aus dem Calc-Verzeichnis importiert. Dies ist der Code, der tatsächlich funktioniert.

Mit anderen Worten, seit Python 3.3 können Sie die Module unter dem Verzeichnis verwenden. Wenn Sie sich auf name konzentrieren

calc.add

Wird ausgegeben. Daher scheint es als Add-Modul des Calc-Space geladen zu sein. Dies scheint eine Funktion zu sein, die seit Python 3.3 als "Namespace-Import" bezeichnet wird.

Es funktioniert jedoch nicht gut, wenn Sie Folgendes tun.

main.py



'''
    from calc import add.add
                        ^
SyntaxError: invalid syntax
'''
from calc import add.add
print(add(2, 3))



'''
AttributeError: module 'calc' has no attribute 'add'
'''
import calc
print(calc.add.add(2, 3))

Anscheinend scheint es nicht erlaubt zu sein, mit "." In den nach dem Import geschriebenen Inhalten weiter einzugrenzen.

Es scheint auch, dass ** das Lesen des Verzeichnisses als Modul ** nicht erlaubt ist.

Paket

Was ist ein Paket?

Ein Paket ist ein "** Modul **, das alle Module verwaltet". Zum Beispiel habe ich das calc-Verzeichnis früher erstellt.

.
├── calc
│   ├── __pycache__
│   │   ├── add.cpython-37.pyc
│   │   ├── mul.cpython-37.pyc
│   │   └── sub.cpython-37.pyc
│   ├── add.py
│   ├── calc_main.py
│   ├── mul.py
│   └── sub.py

Indem Sie ** __ init __. Py ** in dieses Calc-Verzeichnis einfügen, Sie können sich das Calc-Verzeichnis selbst als ein ** großes Modul ** vorstellen.

Ohne "__init __. Py" ist das calc-Verzeichnis natürlich nur ein "Verzeichnis". Wenn Sie "__init __. Py" eingeben, wird das Calc-Verzeichnis selbst als ** Modul ** betrachtet.

Mithilfe von Paketen können Sie Dateien in größeren Einheiten verarbeiten und strukturieren.

Was ist mit __init __. Py?

__init __. py ist das erste, was ausgeführt wird, wenn Sie dieses Paketmodul aufrufen.

__init__.py


print(__name__)

In diesem Fall wird der Verzeichnisname ausgegeben.

Dies liegt daran, dass das Verzeichnis von "__init __. Py" als "Modul" behandelt wird.

Versuchen Sie, calc neu zu schreiben

Versuchen Sie, das Calc-Verzeichnis für das Paket neu zu schreiben.

calc_main.py


print(__name__)

from . import add
from . import sub
from . import mul

print(add.add(2, 3))

Ich werde versuchen.

Zu diesem Zeitpunkt funktioniert die normale Python-Ausführung nicht.

python calc/calc_main.py
python calc_main.py

Und so weiter

  File "calc_main.py", line 3, in <module>
    from . import add
ImportError: cannot import name 'add'

Fehler tritt auf.

python -m calc.calc_main.py

Dann

Sie können calc_main.py mit calc als Paket ausführen.

Wie Sie sehen können, ist das Paket im Grunde ein "relativer Pfad" und scheint nun angegeben zu sein.

python calc/calc_main.py
python calc_main.py

Das ist der Grund, warum es nicht funktioniert Schreiben Sie mit dem folgenden Code neu.

print(__name__)
print(__package__)

from . import add
from . import sub
from . import mul

print(add.add(2, 3))
python -m calc.calc_main.py

calc
__main__
calc
add.py
calc.add
sub.py
calc.sub
mul.py
calc.mul
5

python calc/calc_main.py

__main__
None
Traceback (most recent call last):
  File "calc/calc_main.py", line 4, in <module>
    from . import add
ImportError: cannot import name 'add'

Es wird sein.

Hier als Unterschied zwischen ihnen Zu welchem Paket gehört package? Repräsentiert (übergeordnetes Modul) Bei demjenigen, der nicht funktioniert, lautet das Attribut package None. Daher weiß ich nicht, auf welches Paket ich mich beziehen soll, und es wird eine Fehlermeldung angezeigt. Mit anderen Worten, selbst wenn Sie "." Usw. angeben, ist dies "Relativer Pfad von welchem Paket?".

aus diesem Grund, Wenn Sie das Calc-Paket aus dem Hauptverzeichnis verwenden

main.py



from calc import calc_main

print(10)
calc
calc.calc_main
calc
add.py
calc.add
sub.py
calc.sub
mul.py
calc.mul
5
10

Es wird ordnungsgemäß ausgeführt.

Daher scheint es in der Situation gut zu funktionieren, in der das Attribut __package__ richtig angegeben ist, und im Fall eines relativen Imports.

Referenzseite [[Python] Stolperstein importieren](https://qiita.com/ysk24ok/items/2711295d83218c699276#package kann den impliziten relativen Import nicht verwenden) Ich habe versucht, die Python-Module zusammenzufassen Idee zu Python: Unterschiede zwischen Python-Paketen und -Modulen

Ich werde das Modulpaket mit der Option -m richtig angeben.

In PyCharm?

Was soll ich tun, wenn ich PyCharm verwende? Anscheinend verhält sich PyCharm anders als normales Python. IDE scheint eine gute Vermutung anzustellen und sich anders zu verhalten.

1. Verwenden Sie beim Laden von Modulen den relativen Pfad

Relative Pfade werden beim Laden von Modulen innerhalb eines Pakets verwendet.

Im selben Paket wird der relative Pfad verwendet.

calc_main.py


print(__name__)
print(__package__)

from . import add

print(add.add(2, 3))

2. Wenn Sie das Paket verwenden, schreiben Sie wie gewohnt

Wenn Sie das Paket von oben treffen, können Sie es so lassen, wie es ist. Nennen Sie es wie ein normales Modul.

main.py


from calc import calc_main

print(10)

3. Die Datei kann nicht im Paket gelesen werden. Führen Sie dies über den Befehl aus

In PyCharm gibt es eine Startkonfigurationsausführung usw. Beim Versuch, eine Datei in einem Paket auszuführen

calc_main.py


print(__name__)
print(__package__)

from . import add

print(add.add(2, 3))

Mit package wird keine ausgegeben, und es tritt ein Fehler auf, weil das Paket nicht beurteilt wird. In einem solchen Fall

Über die Befehlszeile

python -m calc.calc_main

Sie können es als geben.

Das Ausführen der PyCharm-Startkonfiguration funktioniert nicht. Es ist ärgerlich, dass es schwierig ist, die Ausführung einer einzelnen Datei zu testen ... Gibt es eine Möglichkeit, es gut zu machen ...

https://pleiades.io/help/pycharm/content-root.html

Recommended Posts

Lernen Sie Python-Pakete und -Module kennen
Python-Grundkurs (14 Module und Pakete)
Organisieren Sie Python-Module und -Pakete in einem Chaos
Erhalten Sie ein abstraktes Verständnis der Python-Module und -Pakete
Pakete, die MIDI mit Python Midi und Pretty_Midi verarbeiten
[Python / matplotlib] FuncAnimation verstehen und verwenden
Informationen zu Python Primer-Modulen und bedingten Ausdrücken
Virtuelle Python-Umgebung und Pakete unter Ubuntu
[Python] Packen und verteilen Sie Ihre eigenen Module
Verstehen Sie Python-Listen, Wörterbücher und so weiter.
[Python] Komprimieren und dekomprimieren
Liste der Python-Module
Python- und Numpy-Tipps
[Python] Pip und Wheel
Python Iterator und Generator
Ruby, Python und Map
Python-Eingabe und Ausgabe
Verwenden von Python # externen Paketen
Python und Ruby teilen sich
Python asyncio und ContextVar
Python - Erläuterung und Zusammenfassung der Verwendung der 24 wichtigsten Pakete
Verstehen Sie die Exponentialverteilung sorgfältig und zeichnen Sie in Python
Zeichnen und verstehen Sie die multivariate Normalverteilung in Python
Verstehe die Poisson-Distribution sorgfältig und zeichne in Python
Verwalten Sie Python-Laufzeitpakete und Entwicklungsumgebungspakete mit Poetry
Programmieren mit Python und Tkinter
Ver- und Entschlüsselung mit Python
Verstehen Sie t-SNE und verbessern Sie die Visualisierung
Python: Klassen- und Instanzvariablen
3-3, Python-Zeichenfolge und Zeichencode
Python 2-Serie und 3-Serie (Anaconda Edition)
Python und Hardware-Verwenden von RS232C mit Python-
Python auf Ruby und wütend Ruby auf Python
Grundlegendes zu PyTorchs DataSet und DataLoader (2)
Python-Einzug und String-Format
[Python] Laden von selbst erstellten mehrstufigen Modulen
Python Real Number Division (/) und Integer Division (//)
Installieren Sie Python und Flask (Windows 10)
Grundlegendes zu PyTorchs DataSet und DataLoader (1)
Informationen zu Python-Objekten und -Klassen
Listet Methodenargumentinformationen für Klassen und Module in Python auf
Informationen zu Python-Variablen und -Objekten
Versuchen Sie, Python selbst zu verstehen
Apache mod_auth_tkt und Python AuthTkt
Å (Ongustorome) und NFC @ Python
# 2 [python3] Trennung und Kommentar aus
Flache Python-Kopie und tiefe Kopie
Python und Ruby Slice Memo
Python-Installation und grundlegende Grammatik
Ich habe Java und Python verglichen!
Flache Python-Kopie und tiefe Kopie
Über Python, len () und randint ()
Eine Standardmethode zum Entwickeln und Verteilen von Paketen in Python
Informationen zu Python-Datums- und Zeitzone
Installieren Sie Python 3.7 und Django 3.0 (CentOS)
Python-Umgebungskonstruktion und TensorFlow
Python-Klassen- und Instanzvariablen
Roadmap zum Veröffentlichen von Python-Paketen