Python3-Modul

In den vorherigen Kapiteln haben wir grundsätzlich den Python-Interpreter zum Programmieren verwendet. Wenn Sie den Python-Interpreter beenden und erneut starten, verschwinden alle Methoden und Variablen, die Sie definiert haben.

Um dies zu lösen, bietet Python eine Möglichkeit, diese Definitionen in einer Datei zu speichern, die von Skripten oder interaktiven Interpreter-Instanzen verwendet werden kann. Diese Datei wird als Modul bezeichnet.

Ein Modul in Python ist eine Datei, die Python-Definitionen und -Anweisungen enthält. Der Dateiname ist der Modulname plus das.py-Suffix.

Ein Modul kann Funktionen, Klassen, Variablen und ausführbaren Code enthalten. Durch Module können wir Code in wiederverwendbare Einheiten organisieren, um Verwaltung und Wartung zu erleichtern.

Die Rolle von Modulen

  • Code-Wiederverwendung: Kapseln Sie gemeinsame Funktionalität in Module ein, die in mehreren Programmen wiederverwendet werden können.

  • Namensraumverwaltung: Module können Namenskonflikte vermeiden; Funktionen oder Variablen mit demselben Namen in verschiedenen Modulen stören sich nicht gegenseitig.

  • Code-Organisation: Unterteilen Sie Code nach Funktion in verschiedene Module, wodurch die Programmstruktur klarer wird.

Das Folgende ist ein Beispiel für die Verwendung eines Moduls aus der Python-Standardbibliothek.

Beispiel (Python 3.0+)

#!/usr/bin/python3 # Dateiname: using_sys.py import sys print('Die Kommandozeilenargumente sind wie folgt:') for i in sys.argv: print(i) print('\n\nDer Python-Pfad ist:', sys.path, '\n')

Das Ausführungsergebnis ist wie folgt:

$ python using_sys.py 参数1 参数2
命令行参数如下:
using_sys.py
参数1
参数2


Python 路径为: ['/root', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages'] 

  • 1. import sys importiert das Modul sys.py aus der Python-Standardbibliothek; dies ist eine Möglichkeit, ein Modul zu importieren.
  • 2. sys.argv ist eine Liste, die Kommandozeilenargumente enthält.
  • 3. sys.path enthält eine Liste von Pfaden, in denen der Python-Interpreter automatisch nach benötigten Modulen sucht.

import-Anweisung

Um eine Python-Quelldatei zu verwenden, führen Sie einfach eine import-Anweisung in einer anderen Quelldatei aus. Die Syntax lautet wie folgt:

import module1[, module2[,... moduleN]

Wenn der Interpreter auf eine import-Anweisung stößt, wird das Modul importiert, sofern es sich im aktuellen Suchpfad befindet.

Der Suchpfad ist eine Liste aller Verzeichnisse, die der Interpreter durchsucht. Wenn Sie das Modul support importieren möchten, müssen Sie den Befehl am Anfang des Skripts einfügen:

Code der Datei support.py

#!/usr/bin/python3 # Dateiname: support.py def print_func( par ): print ("Hello : ", par) return

test.py importiert das Modul support:

Code der Datei test.py

#!/usr/bin/python3 # Dateiname: test.py # Modul importieren import support # Jetzt können Sie die im Modul enthaltenen Funktionen aufrufen support.print_func("Beispiel")

Die Ausgabe des obigen Beispiels ist:

$ python3 test.py 
Hello :  Example

Code herunterladen

Ein Modul wird nur einmal importiert, egal wie oft Sieimportausführen. Dadurch wird verhindert, dass das importierte Modul immer wieder ausgeführt wird.

Wenn wir die import-Anweisung verwenden, wie findet der Python-Interpreter die entsprechende Datei?

Dies betrifft den Suchpfad von Python. Der Suchpfad besteht aus einer Reihe von Verzeichnisnamen, und der Python-Interpreter sucht das importierte Modul der Reihe nach in diesen Verzeichnissen.

Modulsuchpfad

Beim Importieren eines Moduls sucht Python das Modul in der folgenden Reihenfolge:

  1. Das aktuelle Verzeichnis.

  2. UmgebungsvariablePYTHONPATHAngegebenes Verzeichnis.

  3. Das Verzeichnis der Python-Standardbibliothek.

  4. .pthDas in der Datei angegebene Verzeichnis.

Der Suchpfad wird zur Kompilierungs- oder Installationszeit von Python festgelegt, und die Installation neuer Bibliotheken kann ihn ebenfalls ändern. Der Suchpfad ist in der Variable path im Modul sys gespeichert. Machen wir ein einfaches Experiment: Geben wir im interaktiven Interpreter den folgenden Code ein:

>>> import sys
>>> sys.path
['', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']
>>> 

Die Ausgabe von sys.path ist eine Liste, deren erstes Element eine leere Zeichenkette '' ist, die das aktuelle Verzeichnis repräsentiert (wenn sie aus einem Skript ausgegeben wird, kann man deutlicher sehen, um welches Verzeichnis es sich handelt), also das Verzeichnis, in dem wir den Python-Interpreter ausführen (bei Skripten ist es das Verzeichnis, in dem das laufende Skript liegt).

Wenn daher, wie in meinem Fall, im aktuellen Verzeichnis eine Datei mit demselben Namen wie das zu importierende Modul vorhanden ist, verdeckt sie das zu importierende Modul.

Nachdem du das Konzept des Suchpfads verstanden hast, kannst dusys.pathändern, um einige Module zu importieren, die sich nicht im Suchpfad befinden.

Erstellen Sie nun eine Datei namens fibo.py im aktuellen Verzeichnis des Interpreters oder in einem Verzeichnis innerhalb von sys.path. Der Code lautet wie folgt:

Beispiel

# Modul für Fibonacci-Folge def fib(n): # Die Fibonacci-Folge bis n definieren a, b = 0, 1 while b < n: print(b, end=' ') a, b = b, a+b print() def fib2(n): # Die Fibonacci-Folge bis n zurückgeben result = [] a, b = 0, 1 while b < n: result.append(b) a, b = b, a+b return result

Starten Sie dann den Python-Interpreter und verwenden Sie den folgenden Befehl, um dieses Modul zu importieren:

>>> import fibo

Dadurch werden nicht die direkt in fibo definierten Funktionsnamen in die aktuelle Symboltabelle geschrieben; es wird dort nur der Name des Moduls fibo geschrieben.

Sie können den Modulnamen verwenden, um auf Funktionen zuzugreifen:

Beispiel

>>>fibo.fib(1000) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 >>> fibo.fib2(100) [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] >>> fibo.__name__ 'fibo'

Wenn Sie eine Funktion häufig verwenden möchten, können Sie sie einem lokalen Namen zuweisen:

>>> fib = fibo.fib
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377


from ... import-Anweisung

Pythons from-Anweisung ermöglicht es Ihnen, einen bestimmten Teil aus einem Modul in den aktuellen Namensraum zu importieren. Die Syntax lautet wie folgt:

from modname import name1[, name2[, ... nameN]]

Um beispielsweise die Funktion fib aus dem Modul fibo zu importieren, verwenden Sie die folgende Anweisung:

>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

Diese Deklaration importiert nicht das gesamte Modul fibo in den aktuellen Namensraum; sie bringt nur die Funktion fib aus fibo herein.

Aliasing von Modulen

Verwenden Sie dasasSchlüsselwort, um ein Modul oder eine Funktion mit einem Alias zu versehen:

import numpy as np  # 将 numpy 模块别名设置为 np
from math import sqrt as square_root  # 将 sqrt 函数别名设置为 square_root


from ... import *-Anweisung

Das Importieren aller Inhalte eines Moduls in den aktuellen Namensraum ist ebenfalls möglich; verwenden Sie einfach die folgende Deklaration:

from modname import *

Dies bietet eine einfache Möglichkeit, alle Elemente aus einem Modul zu importieren.

Nicht empfohlen, da es leicht zu Namenskonflikten führen kann.


Tiefer Einblick in Module

Neben Methodendefinitionen kann ein Modul auch ausführbaren Code enthalten. Dieser Code wird im Allgemeinen verwendet, um das Modul zu initialisieren. Er wird nur ausgeführt, wenn das Modul zum ersten Mal importiert wird.

Jedes Modul hat seine eigene unabhängige Symboltabelle, die als globale Symboltabelle für alle Funktionen innerhalb des Moduls verwendet wird.

Daher können Modulautoren diese globalen Variablen innerhalb des Moduls sicher verwenden, ohne befürchten zu müssen, sie mit den globalen Variablen anderer Benutzer zu verwechseln.

Andererseits können Sie, wenn Sie wirklich wissen, was Sie tun, auch mit einer Schreibweise wie modname.itemname auf Funktionen innerhalb des Moduls zugreifen.

Module können andere Module importieren. Verwenden Sie import am Anfang eines Moduls (oder Skripts oder an anderer Stelle), um ein Modul zu importieren. Natürlich ist dies nur eine Konvention, nicht zwingend erforderlich. Der Name des importierten Moduls wird in die Symboltabelle des aktuell bearbeiteten Moduls eingefügt.

Es gibt eine weitere Möglichkeit zu importieren: Sie können mit import Namen (Funktionen, Variablen) direkt aus einem Modul in das aktuell bearbeitete Modul importieren. Zum Beispiel:

>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

Diese Importmethode fügt den Namen des importierten Moduls nicht in die aktuelle Symboltabelle ein (in diesem Beispiel ist der Name fibo also nicht definiert).

Es gibt noch eine weitere Methode, mit der alle Namen (Funktionen, Variablen) in einem Modul auf einmal in die Symboltabelle des aktuellen Moduls importiert werden können:

>>> from fibo import *
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

Dies importiert alle Namen, aber Namen, die mit einem einzelnen Unterstrich (_) beginnen, sind nicht enthalten. In den meisten Fällen verwenden Python-Programmierer diese Methode nicht, weil Namen, die aus anderen Quellen importiert werden, bestehende Definitionen überschreiben können.


__name__-Attribut

Wenn ein Modul zum ersten Mal von einem anderen Programm importiert wird, wird sein Hauptprogramm ausgeführt.

Wenn wir möchten, dass ein bestimmter Codeblock im Modul nicht ausgeführt wird, wenn das Modul importiert wird, können wir das__name__Attribut verwenden, damit dieser Block nur ausgeführt wird, wenn das Modul selbst ausgeführt wird.

#!/usr/bin/python3
# Filename: using_name.py

if __name__ == '__main__':
   print('程序自身在运行')
else:
   print('我来自另一模块')

Die Laufzeitausgabe lautet wie folgt:

$ python using_name.py
程序自身在运行
$ python
>>> import using_name
我来自另一模块
>>>

Erklärung: Jedes Modul hat ein __name__-Attribut.

  • Wenn das Modul direkt ausgeführt wird,__name__ist sein Wert__main__。

  • Wenn das Modul importiert wird,__name__ist sein Wert der Modulname.

Hinweis:__name__und__main__Es sind doppelte Unterstriche darunter,_ _um das Leerzeichen dazwischen zu entfernen.


dir()-Funktion

Die eingebaute Funktion dir() kann alle in einem Modul definierten Namen finden. Sie gibt sie als Liste von Zeichenketten zurück:

>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)  
['__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__',
 '__package__', '__stderr__', '__stdin__', '__stdout__',
 '_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe',
 '_home', '_mercurial', '_xoptions', 'abiflags', 'api_version', 'argv',
 'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder',
 'call_tracing', 'callstats', 'copyright', 'displayhook',
 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix',
 'executable', 'exit', 'flags', 'float_info', 'float_repr_style',
 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags',
 'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit',
 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount',
 'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
 'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path',
 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1',
 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit',
 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout',
 'thread_info', 'version', 'version_info', 'warnoptions']

Wenn kein Argument angegeben wird, listet die Funktion dir() alle aktuell definierten Namen auf:

>>> a = [1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir() # 得到一个当前模块中定义的属性列表
['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']
>>> a = 5 # 建立一个新的变量 'a'
>>> dir()
['__builtins__', '__doc__', '__name__', 'a', 'sys']
>>>
>>> del a # 删除变量名a
>>>
>>> dir()
['__builtins__', '__doc__', '__name__', 'sys']
>>>

Standardmodule

Python selbst verfügt über einige Standardmodulbibliotheken, die in der Python Library Reference (das heißt der späteren "Library Reference") vorgestellt werden.

ModulnameBeschreibung
mathMathematische Operationen (wie Quadratwurzel, trigonometrische Funktionen usw.)
osBetriebssystembezogene Funktionen (wie Datei- und Verzeichnisoperationen)
sysSystembezogene Parameter und Funktionen
randomZufallszahlen generieren
datetimeDatum und Uhrzeit verarbeiten
jsonJSON-Daten verarbeiten
reOperationen mit regulären Ausdrücken
collectionsZusätzliche Datenstrukturen bereitstellen (wie defaultdict, deque)
itertoolsIterator-Werkzeuge bereitstellen
functoolsWerkzeuge für Funktionen höherer Ordnung (wie reduce, lru_cache)

Einige Module sind direkt in den Interpreter integriert. Obwohl sie keine eingebauten Bestandteile der Sprache sind, können sie sehr effizient verwendet werden, sogar für Systemaufrufe.

Diese Komponenten sind je nach Betriebssystem unterschiedlich konfiguriert. Zum Beispiel wird das Modul winreg nur auf Windows-Systemen bereitgestellt.

Beachten Sie, dass es ein spezielles Modul gibt, sys, das in jeden Python-Interpreter integriert ist. Die Variablen sys.ps1 und sys.ps2 definieren die Zeichenfolgen, die den primären und sekundären Eingabeaufforderungen entsprechen:

>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
C> print('Example!')
Example!
C> 

Paket

Pakete sind eine Möglichkeit, Python-Modul-Namensräume mithilfe von "gepunkteten Modulnamen" zu verwalten.

Wenn der Name eines Moduls beispielsweise A.B ist, dann repräsentiert es ein Untermodul B in einem Paket A.

So wie Sie sich bei der Verwendung von Modulen keine Sorgen machen müssen, dass globale Variablen sich zwischen verschiedenen Modulen gegenseitig beeinflussen, bedeutet die Verwendung gepunkteter Modulnamen ebenfalls, dass Sie sich keine Sorgen um Module mit demselben Namen zwischen verschiedenen Bibliotheken machen müssen.

Auf diese Weise können verschiedene Autoren NumPy-Module oder Python-Grafikbibliotheken bereitstellen.

Angenommen, Sie möchten eine Reihe von Modulen (oder ein "Paket") entwerfen, um Audiodateien und -daten einheitlich zu verarbeiten.

Es gibt viele verschiedene Audio-Dateiformate (grundsätzlich anhand ihrer Dateiendungen unterschieden, zum Beispiel: .wav, :file:.aiff, :file:.au), daher benötigen Sie eine ständig wachsende Menge an Modulen, um zwischen verschiedenen Formaten zu konvertieren.

Und für diese Audiodaten gibt es ebenfalls viele verschiedene Operationen (wie Mischen, Hinzufügen von Echo, Hinzufügen von Equalizer-Funktionen, Erzeugen künstlicher Stereo-Effekte), daher benötigen Sie auch eine endlose Menge an Modulen, um diese Operationen zu verarbeiten.

Hier ist eine mögliche Paketstruktur (in einem hierarchischen Dateisystem):

sound/                          顶层包
      __init__.py               初始化 sound 包
      formats/                  文件格式转换子包
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      effects/                  声音效果子包
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      filters/                  filters 子包
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...

Beim Importieren eines Pakets durchsucht Python die Verzeichnisse in sys.path, um die im Paket enthaltenen Unterverzeichnisse zu finden.

Ein Verzeichnis wird nur dann als Paket erkannt, wenn es eine Datei namens __init__.py enthält. Dies dient hauptsächlich dazu, zu verhindern, dass einige übermäßig gebräuchliche Namen (wie string) versehentlich gültige Module im Suchpfad beeinflussen.

Im einfachsten Fall platzieren Sie einfach eine leere :file:__init__.py-Datei. Natürlich kann diese Datei auch etwas Initialisierungscode enthalten oder der __all__-Variable einen Wert zuweisen (wird später vorgestellt).

Benutzer können jeweils nur ein bestimmtes Modul aus einem Paket importieren, zum Beispiel:

import sound.effects.echo

Dies importiert das Submodul: sound.effects.echo. Es muss über seinen vollständigen Namen angesprochen werden:

sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

Es gibt eine andere Möglichkeit, ein Submodul zu importieren:

from sound.effects import echo

Dies importiert ebenfalls das Submodul: echo, und es sind nicht diese langen Präfixe erforderlich, sodass es so verwendet werden kann:

echo.echofilter(input, output, delay=0.7, atten=4)

Eine andere Variante ist, direkt eine Funktion oder Variable zu importieren:

from sound.effects.echo import echofilter

Ebenso importiert diese Methode das Submodul: echo, und Sie können direkt seine Funktion echofilter() verwenden:

echofilter(input, output, delay=0.7, atten=4)

Beachten Sie, dass bei Verwendung vonfrom package import itemin dieser Form das entsprechende Element entweder ein Submodul (Unterpaket) im Paket oder andere im Paket definierte Namen wie Funktionen, Klassen oder Variablen sein kann.

Die import-Anweisung behandelt item zunächst als einen im Paket definierten Namen. Wenn item nicht gefunden wird, versucht sie anschließend, es als Modul zu importieren. Wenn es immer noch nicht gefunden wird, löst sie eine:exc:ImportErrorAusnahme aus.

Umgekehrt: Wenn Sie eine Form wieimport item.subitem.subsubitemin dieser Importform verwenden, muss alles außer dem letzten Element ein Paket sein, und das letzte Element kann ein Modul oder ein Paket sein, aber es darf nicht der Name einer Klasse, Funktion oder Variable sein.


Importieren von * aus einem Paket

Wenn wirfrom sound.effects import *verwenden, was wird dann passieren?

Python wird das Dateisystem durchsuchen, alle Submodule im Paket finden und sie alle nacheinander importieren.

Aber diese Methode funktioniert auf der Windows-Plattform nicht sehr gut, weil Windows ein System ist, das nicht zwischen Groß- und Kleinschreibung unterscheidet.

Unter Windows können wir nicht feststellen, ob eine Datei namens ECHO.py als Modul namens echo, Echo oder ECHO importiert wird.

Um dieses Problem zu lösen, müssen wir nur einen expliziten Paketindex angeben.

Die import-Anweisung folgt dieser Regel: Wenn die Paketdefinitionsdatei __init__.pyeine Listenvariable namens__all__enthält, dann beim Verwenden vonfrom package import *Alle Namen in dieser Liste werden als Inhalte des Pakets importiert.

Vergessen Sie als Paketautor nicht, sicherzustellen, dass nach der Aktualisierung des Pakets__all__ebenfalls aktualisiert wird.

Das folgende Beispiel enthält den folgenden Code in der Datei:sounds/effects/__init__.py:

__all__ = ["echo", "surround", "reverse"]

Das bedeutet, dass Sie bei Verwendung von from sound.effects import * nur diese drei Untermodule im Paket importieren.

Wenn__all__wirklich nicht definiert ist, dann wird bei Verwendung vonfrom sound.effects import *mit dieser Syntax kein Untermodul aus dem Paket sound.effects importiert. Es importiert nur das Paket sound.effects und alle darin definierten Inhalte (möglicherweise wird der in __init__.py definierte Initialisierungscode ausgeführt).

Dies importiert alle in __init__.py definierten Namen. Und es wird keine der explizit angegebenen Module beeinträchtigen, die wir vor dieser Anweisung importiert haben. Sehen Sie sich diesen Teil des Codes an:

import sound.effects.echo
import sound.effects.surround
from sound.effects import *

In diesem Beispiel wurden vor dem Ausführen von from...import die Module echo und surround im Paket sound.effects bereits in den aktuellen Namensraum importiert. (Natürlich gibt es überhaupt kein Problem, wenn __all__ definiert ist.)

Normalerweise empfehlen wir nicht die Verwendung von*dieser Methode zum Importieren von Modulen, da sie oft die Lesbarkeit des Codes verringert. Sie kann jedoch tatsächlich viel Tipparbeit sparen, und einige Module sind so konzipiert, dass sie nur über bestimmte Methoden importiert werden können.

Denken Sie daran: Die Verwendung vonfrom Package import specific_submoduleist niemals falsch. Tatsächlich ist sie auch die empfohlene Methode. Es sei denn, das Untermodul, das Sie importieren möchten, hat möglicherweise denselben Namen wie ein Untermodul in einem anderen Paket.

Wenn das Paket ein Unterpaket in der Struktur ist (zum Beispiel in diesem Fall für das Paket sound) und Sie ein Geschwisterpaket importieren möchten (ein Paket auf derselben Ebene), müssen Sie einen absoluten Pfad verwenden, um es zu importieren. Wenn zum Beispiel das Modul sound.filters.vocoder das Modul echo aus dem Paket sound.effects verwenden möchte, müssen Sie from sound.effects import echo schreiben.

from . import echo
from .. import formats
from ..filters import equalizer

Sowohl implizite als auch explizite relative Importe beginnen beim aktuellen Modul. Der Name des Hauptmoduls ist immer "__main__". Das Hauptmodul einer Python-Anwendung sollte immer absolute Pfadverweise verwenden.

Pakete bieten auch ein zusätzliches Attribut __path__. Dies ist eine Liste von Verzeichnissen, wobei jedes Verzeichnis, das dieses Paket enthält, eine __init__.py besitzt, die diesem Paket dient. Sie müssen es definieren, bevor andere __init__.py-Dateien ausgeführt werden. Diese Variable kann geändert werden, um die im Paket enthaltenen Module und Unterpakete zu beeinflussen.

Diese Funktion wird nicht häufig verwendet; sie wird im Allgemeinen verwendet, um die Module in einem Paket zu erweitern.

Weitere Erweiterungen