Rheinwerk Computing < openbook >

 
Inhaltsverzeichnis
1 Einleitung
2 Die Programmiersprache Python
Teil I Einstieg in Python
3 Erste Schritte im interaktiven Modus
4 Der Weg zum ersten Programm
5 Kontrollstrukturen
6 Dateien
7 Das Laufzeitmodell
8 Funktionen, Methoden und Attribute
9 Informationsquellen zu Python
Teil II Datentypen
10 Das Nichts – NoneType
11 Operatoren
12 Numerische Datentypen
13 Sequenzielle Datentypen
14 Zuordnungen
15 Mengen
16 Collections
17 Datum und Zeit
18 Aufzählungstypen – Enum
Teil III Fortgeschrittene Programmiertechniken
19 Funktionen
20 Modularisierung
21 Objektorientierung
22 Ausnahmebehandlung
23 Iteratoren
24 Kontextobjekte
25 Manipulation von Funktionen und Methoden
Teil IV Die Standardbibliothek
26 Mathematik
27 Kryptografie
28 Reguläre Ausdrücke
29 Schnittstelle zu Betriebssystem und Laufzeitumgebung
30 Kommandozeilenparameter
31 Dateisystem
32 Parallele Programmierung
33 Datenspeicherung
34 Netzwerkkommunikation
35 Debugging und Qualitätssicherung
36 Dokumentation
Teil V Weiterführende Themen
37 Anbindung an andere Programmiersprachen
38 Distribution von Python-Projekten
39 Grafische Benutzeroberflächen
40 Python als serverseitige Programmiersprache im WWW – ein Einstieg in Django
41 Wissenschaftliches Rechnen
42 Insiderwissen
43 Von Python 2 nach Python 3
A Anhang
Stichwortverzeichnis

Download:
- Beispielprogramme, ca. 464 KB

Jetzt Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Python 3 von Johannes Ernesti, Peter Kaiser
Das umfassende Handbuch
Buch: Python 3

Python 3
Pfeil 20 Modularisierung
Pfeil 20.1 Einbinden globaler Module
Pfeil 20.2 Lokale Module
Pfeil 20.2.1 Namenskonflikte
Pfeil 20.2.2 Modulinterne Referenzen
Pfeil 20.2.3 Module ausführen
Pfeil 20.3 Pakete
Pfeil 20.3.1 Importieren aller Module eines Pakets
Pfeil 20.3.2 Namespace Packages
Pfeil 20.3.3 Relative Import-Anweisungen
Pfeil 20.4 Das Paket importlib
Pfeil 20.4.1 Einbinden von Modulen und Paketen
Pfeil 20.4.2 Verändern des Import-Verhaltens
 
Zum Seitenanfang

20.3    Pakete Zur vorigen ÜberschriftZur nächsten Überschrift

Python ermöglicht es Ihnen, mehrere Module in einem Paket zu kapseln. Das ist vorteilhaft, wenn diese Module thematisch zusammengehören. Ein Paket kann im Gegensatz zu einem einzelnen Modul beliebig viele weitere Pakete enthalten, die ihrerseits wieder Module bzw. Pakete enthalten können.

Um ein Paket zu erstellen, muss ein Unterordner im Programmverzeichnis erzeugt werden. Der Name des Ordners entspricht dem Namen des Pakets. Zusätzlich kann[ 82 ](Bei Python-Versionen vor 3.3 muss jedes Paket eine __init__.py enthalten. Mit Python 3.3 wurden Namespace Packages eingeführt, die keine __init__.py enthalten. Näheres zu Namespace Packages erfahren Sie in Abschnitt 20.3.2. ) in diesem Ordner eine Programmdatei namens __init__.py[ 83 ](Beachten Sie, dass es sich jeweils um zwei Unterstriche vor und hinter »init« handelt. ) vorhanden sein. Diese Datei enthält Initialisierungscode, der beim Einbinden des Pakets einmalig ausgeführt wird.

[»]  Hinweis

Wenn in demselben Verzeichnis ein Paket und ein Modul gleichen Namens existieren, kommt es zu einem Namenskonflikt. Es ist grundsätzlich so, dass bei Namensgleichheit ein Paket Vorrang vor einem Modul hat, es also keine direkte Möglichkeit mehr gibt, das Modul zu importieren.

Ein Programm mit mehreren Paketen und Unterpaketen hat eine ähnliche Verzeichnisstruktur wie in Abbildung 20.1 dargestellt.

Paketstruktur eines Beispielprogramms

Abbildung 20.1    Paketstruktur eines Beispielprogramms

Es handelt sich um die Verzeichnisstruktur eines fiktiven Bildbearbeitungsprogramms. Das Hauptprogramm befindet sich in der Datei program.py. Neben dem Hauptprogramm existieren im Programmverzeichnis zwei Pakete:

  • Das Paket effects soll bestimmte Effekte auf ein bereits geladenes Bild anwenden. Dazu enthält das Paket neben der Datei __init__.py drei Module, die jeweils für einen grundlegenden Effekt sorgen. Es handelt sich um die Module blur (zum Verwischen des Bildes), flip (zum Spiegeln des Bildes) und rotate (zum Drehen des Bildes).
  • Das Paket formats soll dazu in der Lage sein, bestimmte Grafikformate zu lesen und schreiben. Dazu nehmen wir an, dass in seiner __init__.py zwei Funktionen namens readImage und writeImage definiert sind. Es soll hier nicht näher auf Funktionsschnittstellen eingegangen werden. Damit das Lesen und Schreiben von Grafiken diverser Formate möglich ist, enthält das Paket formats zwei Unterpakete namens bmp und png, die je zwei Module zum Lesen bzw. Schreiben des entsprechenden Formats umfassen.

Im Hauptprogramm werden zunächst die Pakete effects und formats eingebunden und verwendet:

>>> import effects
>>> import formats

Durch die import-Anweisung wird die Programmdatei __init__.py des einzubindenden Pakets ausgeführt und der Inhalt dieser Datei als Modul in einem eigenen Namensraum verfügbar gemacht. So könnten Sie nach den oben erläuterten import-Anweisungen folgendermaßen auf die Funktionen readImage und writeImage zugreifen:

>>> formats.readImage()
>>> formats.writeImage()

Um das nun geladene Bild zu modifizieren, soll diesmal ein Modul des Pakets effects geladen werden. Dazu wird bei der import-Anweisung der Paketname durch einen Punkt vom Modulnamen getrennt:

>>> import effects.blur

In diesem Fall wurde das Paket effects vorher eingebunden. Wenn dies nicht der Fall gewesen wäre, würde der Import von effects.blur dafür sorgen, dass zunächst das Paket effects eingebunden und die dazugehörige __init__.py ausgeführt würde. Danach wird das Untermodul blur eingebunden und kann verwendet werden:

>>> effects.blur.blurImage()
[»]  Hinweis

Eine Programmdatei, die sich innerhalb einer Paketstruktur befindet, kann folgendermaßen ausgeführt werden:

python -m formats.png.read

Auf diese Weise wird die gesamte Paketstruktur geladen, sodass relative import-Anweisungen ihre Gültigkeit behalten.

 
Zum Seitenanfang

20.3.1    Importieren aller Module eines Pakets Zur vorigen ÜberschriftZur nächsten Überschrift

Beim Einbinden eines Moduls kann mit from abc import * der gesamte Modulinhalt in den aktuellen Namensraum importiert werden. Dies funktioniert für Pakete nicht, da einige Betriebssysteme, darunter vor allem Windows, bei Datei- und Ordnernamen nicht zwischen Groß- und Kleinschreibung unterscheiden – Python aber sehr wohl. Angenommen, die obige Anweisung würde wie gehabt funktionieren, und abc wäre ein Paket, wäre es beispielsweise unter Windows unklar, ob ein Untermodul namens modul als Modul, MODUL oder modul eingebunden werden soll.

Aus diesem Grund bindet die obige Anweisung nicht alle im Paket enthaltenen Module in den aktuellen Namensraum ein, sondern importiert nur das Paket an sich und führt den Initialisierungscode in __init__.py aus. Alle in dieser Datei angelegten Referenzen werden in den aktuellen Namensraum eingeführt.

Es gibt zwei Möglichkeiten, das gewünschte Verhalten der oben genannten Anweisung zu erreichen. Beide müssen durch den Autor des Pakets implementiert werden.

  • Zum einen können alle Module des Pakets innerhalb der __init__.py per import-Anweisung importiert werden. Dies hat zur Folge, dass sie beim Einbinden des Pakets und damit nach dem Ausführen des Codes der __init__.py-Datei eingebunden wären.
  • Zum anderen kann dies durch Anlegen einer Referenz namens __all__ geschehen. Diese muss eine Liste von Strings mit den zu importierenden Modulnamen referenzieren:
    __all__ = ["blur", "flip", "rotate"]

Es liegt im Ermessen des Programmierers, welches Verhalten from abc import * bei seinen Paketen zeigen soll. Beachten Sie aber, dass das Importieren des kompletten Modul- bzw. Paketinhalts in den aktuellen Namensraum zu unerwünschten Namenskonflikten führen kann. Aus diesem Grund sollten Sie importierte Module stets in einem eigenen Namensraum führen.

 
Zum Seitenanfang

20.3.2    Namespace Packages Zur vorigen ÜberschriftZur nächsten Überschrift

Mit Python 3.3 wurden Pakete eingeführt, die aus mehreren Teilen bestehen können, die an verschiedenen Orten gespeichert sind. Dies ist zum Beispiel dann interessant, wenn mehrere Komponenten einer zusammengehörigen Bibliothek unabhängig voneinander verteilt werden sollen. Beim Einbinden eines solchen Pakets werden die einzelnen Komponenten demselben Namensraum zugewiesen.

Da zu einem Namespace Package mehrere Ordner gehören können, gibt es keine eindeutige __init__.py mehr. Im Gegenteil: Das Vorhandensein bzw. Nichtvorhandensein der __init__.py entscheidet, ob ein Paket als reguläres Paket oder als Namespace Package eingebunden wird.

Angenommen, es existierten zwei Ordner namens package an verschiedenen Orten im Dateisystem, an denen Python nach Modulen und Paketen sucht.[ 84 ](Das sind entweder das lokale Programmverzeichnis, das globale Modulverzeichnis oder jedes andere Verzeichnis, das in der Umgebungsvariablen PYTHONPATH bzw. in der Liste sys.path enthalten ist. ) Beide Ordner haben den gleichen Namen, enthalten aber verschiedene Module, die jeweils ihren Namen ausgeben: verzeichnis1/package/modul1.py und verzeichnis2/package/modul2.py.

Beide Module können nun über den Paketnamen package so eingebunden werden, als seien sie in einem regulären Paket im selben Ordner enthalten:

>>> import package.modul1
modul1
>>> import package.modul2
modul2

Jedes reguläre Paket kann durch Entfernen der __init__.py-Datei zu einem Namespace Package gemacht werden. Beachten Sie aber, dass das Einbinden von Namespace Packages länger dauert als das Einbinden regulärer Pakete, da alle bekannten Verzeichnisse nach Komponenten des Pakets durchsucht werden müssen.

 
Zum Seitenanfang

20.3.3    Relative Import-Anweisungen Zur vorigen ÜberschriftZur nächsten Überschrift

Große Bibliotheken bestehen häufig nicht nur aus einem Modul oder Paket, sondern enthalten diverse Unterpakete, definieren also eine beliebig komplexe Paketstruktur. Innerhalb einer solchen Paketstruktur wird eine relative Variante der import-Anweisung benötigt, die ein Unterpaket anhand einer relativen Pfadangabe einbindet. Auf diese Weise kann ein Paket ein zweites Paket einbinden, das in der Paketstruktur beispielsweise zwei Stufen über dem einbindenden Paket liegt. Eine relative import-Anweisung wird folgendermaßen geschrieben:

from . import xyz

Diese Anweisung bindet das Paket (oder das Modul) xyz aus dem Verzeichnis ein, das zwischen from und import angegeben wird. Ein Punkt steht dabei für das aktuelle Verzeichnis. Jeder weitere Punkt symbolisiert das ein Level höher gelegene Verzeichnis.

Im Kontext des fiktiven Bildbearbeitungsprogramms aus Abbildung 20.1 würde die folgende Anweisung im Modul read des Pakets png das korrespondierende Modul für Bitmaps einbinden:

from ..bmp import read

Es wird aus dem Paket bmp, das sich in der Paketstruktur eine Ebene über dem einbindenden Paket befindet, das Modul read eingebunden.

Eine relative import-Anweisung schlägt fehl, wenn sie außerhalb einer Paketstruktur ausgeführt wird (SystemError) oder wenn eines der Pakete im relativen Pfad zwischen from und import nicht eingebunden ist (NameError).

Die klassische import-Anweisung, wie sie in den vorangegangenen Abschnitten besprochen wurde, wird auch absolute import-Anweisung genannt und kann innerhalb einer Paketstruktur ausschließlich dazu genutzt werden, globale Module einzubinden. In allen anderen Fällen muss eine relative import-Anweisung verwendet werden.

Die eingangs besprochenen Möglichkeiten zur Umbenennung eines eingebundenen Pakets oder Moduls funktionieren auch bei relativen import-Anweisungen:

from ..bmp import read as read_bmp

 


Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

<< zurück
 Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Python 3 Python 3
Jetzt Buch bestellen

 Buchempfehlungen
Zum Rheinwerk-Shop: Einstieg in Python
Einstieg in Python


Zum Rheinwerk-Shop: Python. Der Grundkurs
Python. Der Grundkurs


Zum Rheinwerk-Shop: Algorithmen mit Python
Algorithmen mit Python


Zum Rheinwerk-Shop: Objektorientierte Programmierung
Objektorientierte Programmierung


Zum Rheinwerk-Shop: Raspberry Pi. Das umfassende Handbuch
Raspberry Pi. Das umfassende Handbuch


Zum Rheinwerk-Shop: Roboter-Autos mit dem Raspberry Pi
Roboter-Autos mit dem Raspberry Pi


Zum Rheinwerk-Shop: Neuronale Netze programmieren mit Python
Neuronale Netze programmieren mit Python


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo

 
 


Copyright © Rheinwerk Verlag GmbH 2020
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

 
[Rheinwerk Computing]

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern