Wie schreibe ich ein Python-Modul / -Paket?


Answers

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

Erstellen Sie hello.py und schreiben Sie die folgende Funktion als Inhalt:

def helloworld():
   print "hello"

Dann können Sie hello importieren:

>>> import hello
>>> hello.helloworld()
'hello'
>>>

Um viele .py Dateien zu gruppieren, legen Sie sie in einen Ordner. Jeder Ordner mit einem __init__.py wird von Python als Modul betrachtet und Sie können sie als Paket bezeichnen

|-HelloModule
  |_ __init__.py
  |_ hellomodule.py

Sie können mit der Import-Anweisung auf Ihrem Modul den üblichen Weg gehen.

Weitere Informationen finden Sie unter 6.4. Pakete .

Question

Ich habe Python-Skripte für einfache Aufgaben bei der Arbeit gemacht und nie wirklich darauf geachtet, sie für andere zu verpacken. Jetzt wurde mir zugewiesen, einen Python-Wrapper für eine REST-API zu erstellen. Ich habe absolut keine Ahnung, wie ich anfangen soll und ich brauche Hilfe.

Was ich habe:

(Ich möchte nur so genau wie möglich sein) Ich habe das virtualenv bereit, es ist auch in github , die .gitignore-Datei für Python ist auch da, sowie die Requests-Bibliothek für die Interaktion mit der REST-API. Das ist es.

Hier ist der aktuelle Verzeichnisbaum

.
├── bin
│   └── /the usual stuff/
├── include
│   └── /the usual stuff/
├── lib
│   └── python2.7
│       └── /the usual stuff/
├── local
│   └── /the usual stuff/
└── README.md

27 directories, 280 files

Ich weiß nicht einmal, wo ich die .py-Dateien ablegen soll, wenn ich je eine mache.

Was ich machen wollte:

Mache ein Python-Modul installierbar mit "pip install ..."

Wenn möglich, möchte ich einen allgemeinen Schritt für Schritt Prozess beim Schreiben von Python-Modulen.




Erstellen Sie eine Datei mit dem Namen "hello.py"

Wenn Sie Python 2.x verwenden

def func():
    print "Hello"

Wenn Sie Python 3.x verwenden

def func():
    print("Hello")

Führen Sie die Datei aus. Dann können Sie Folgendes versuchen:

>>> import hello
>>> hello.func()
Hello

Wenn Sie ein wenig hart wollen, können Sie Folgendes verwenden:

Wenn Sie Python 2.x verwenden

def say(text):
    print text

Wenn Sie Python 3.x verwenden

def say(text):
    print(text)

Sehen Sie die in der Klammer neben der Definition? Das ist wichtig. Es ist diejenige, die Sie innerhalb der Definition verwenden können.

Text - Sie können es verwenden, wenn das Programm sagen soll, was Sie wollen. Laut seinem Namen ist es Text. Ich hoffe du weißt was Text bedeutet. Es bedeutet "Wörter" oder "Sätze".

Führen Sie die Datei aus. Dann können Sie Folgendes versuchen, wenn Sie Python 3.x verwenden:

>>> import hello
>>> hello.say("hi")
hi
>>> from hello import say
>>> say("test")
test

Für Python 2.x - ich denke das gleiche mit Python 3? Keine Ahnung. Korrigiere mich, wenn ich einen Fehler auf Python 2.x gemacht habe (ich kenne Python 2, aber ich verwende Python 3)




Da diese Frage des OP noch niemand behandelt hat:

Was ich machen wollte:

Mache ein Python-Modul installierbar mit "pip install ..."

Hier ist ein absolutes minimales Beispiel, das die grundlegenden Schritte zum Vorbereiten und Hochladen Ihres Pakets auf PyPI mit setuptools und twine setuptools .

Dies ist kein Ersatz für das Lesen zumindest des Tutorials , es gibt viel mehr als nur in diesem sehr grundlegenden Beispiel behandelt.

Das Erstellen des Pakets selbst ist hier bereits durch andere Antworten abgedeckt, also nehmen wir an, wir haben diesen Schritt und unsere Projektstruktur so:

.
└── hello/
    ├── __init__.py
    └── hello.py

Um setuptools für das setuptools zu verwenden, müssen wir eine Datei setup.py hinzufügen, die in den Stammordner unseres Projekts geht:

.
├── setup.py
└── hello/
    ├── __init__.py
    └── hello.py

setup.py geben wir die Metadaten für unser Paket an, unser setup.py würde so aussehen:

from setuptools import setup

setup(
    name='hello',
    version='0.0.1',
    description='a pip-installable package example',
    license='MIT',
    packages=['hello'],
    author='Benjamin Gerfelder',
    author_email='benjamin.gerfelder@gmail.com',
    keywords=['example'],
    url='https://github.com/bgse/hello'
)

Da wir license='MIT' , LICENCE.txt wir eine Kopie in unser Projekt als LICENCE.txt , zusammen mit einer Readme-Datei in reStructuredText als README.rst :

.
├── LICENCE.txt
├── README.rst
├── setup.py
└── hello/
    ├── __init__.py
    └── hello.py

An diesem Punkt können wir setuptools , um die Verpackung mit setuptools zu starten. Wenn wir es noch nicht installiert haben, können wir es mit pip installieren:

pip install setuptools

Um dies zu tun und eine setup.py erstellen, rufen wir in unserem Projektstammordner unser setup.py von der Kommandozeile auf und geben sdist :

python setup.py sdist

Dies wird unser Distributionspaket und Ei-Info erstellen, und eine solche Ordnerstruktur ergeben, mit unserem Paket in dist :

.
├── dist/
├── hello.egg-info/
├── LICENCE.txt
├── README.rst
├── setup.py
└── hello/
    ├── __init__.py
    └── hello.py

An diesem Punkt haben wir ein Paket, das wir mit pip installieren können, also von unserem Projektstamm (vorausgesetzt, Sie haben alle Namen wie in diesem Beispiel):

pip install ./dist/hello-0.0.1.tar.gz

Wenn alles gut geht, können wir nun einen Python-Interpreter öffnen, um etwas Verwirrung zu vermeiden, und versuchen, unser glänzendes neues Paket zu verwenden:

Python 3.5.2 (default, Sep 14 2017, 22:51:06) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from hello import hello
>>> hello.greeting()
'Hello !'

Nachdem wir nun bestätigt haben, dass das Paket installiert und funktioniert, können wir es auf PyPI hochladen.

Da wir das Live-Repository nicht mit unseren Experimenten verunreinigen wollen, erstellen wir ein Konto für das Testing-Repository und installieren für den Upload-Prozess twine:

pip install twine

Jetzt sind wir fast da, mit unserem Account erstellen wir einfach twine , um unser Paket hochzuladen, es wird nach unseren Zugangsdaten fragen und unser Paket in das angegebene Repository hochladen:

twine upload --repository-url https://test.pypi.org/legacy/ dist/*

Wir können uns jetzt in unserem Account im PyPI-Test-Repository einloggen und unser frisch hochgeladenes Paket eine Weile bewundern und dann mit pip greifen:

pip install --index-url https://test.pypi.org/simple/ hello

Wie wir sehen können, ist der grundlegende Prozess nicht sehr kompliziert. Wie ich bereits sagte, es gibt viel mehr als hier behandelt, also gehen Sie voran und lesen Sie das Tutorial für eine tiefer gehende Erklärung.




Python 3 - AKTUALISIERT 18. November 2015

Fand die akzeptierte Antwort nützlich, wollte aber aufgrund meiner eigenen Erfahrungen einige Punkte zum Wohle anderer erweitern.

Modul: Ein Modul ist eine Datei, die Python-Definitionen und -Anweisungen enthält. Der Dateiname ist der Modulname mit dem angehängten Suffix .py.

Modul Beispiel : Angenommen, wir haben ein einzelnes Python-Skript im aktuellen Verzeichnis, hier nenne ich es mymodule.py

Die Datei mymodule.py enthält den folgenden Code:

def myfunc():
    print("Hello!")

Wenn wir den Python3-Interpreter aus dem aktuellen Verzeichnis ausführen, können wir die Funktion myfunc auf die folgenden Arten importieren und ausführen (Sie würden normalerweise nur eine der folgenden Möglichkeiten wählen):

>>> import mymodule
>>> mymodule.myfunc()
Hello!
>>> from mymodule import myfunc
>>> myfunc()
Hello!
>>> from mymodule import *
>>> myfunc()
Hello!

Ok, das war einfach genug.

Angenommen, Sie müssen dieses Modul in einen eigenen dedizierten Ordner stellen, um einen Modul-Namespace bereitzustellen, anstatt es nur ad-hoc aus dem aktuellen Arbeitsverzeichnis auszuführen. Hier lohnt es sich, das Konzept eines Pakets zu erklären.

Paket : Pakete sind eine Möglichkeit, den Python-Modul-Namespace zu strukturieren, indem "gepunktete Modulnamen" verwendet werden. Zum Beispiel bezeichnet der Modulname AB ein Submodul namens B in einem Paket namens A. Genauso wie die Verwendung von Modulen die Autoren verschiedener Module davor bewahrt, sich um die globalen Variablennamen der anderen kümmern zu müssen, erspart die Verwendung von punktierten Modulnamen den Autoren von Multi-Modul-Paketen wie NumPy oder der Python Imaging Library, die sich um die Namen der anderen Module kümmern müssen.

Paketbeispiel : Nehmen wir an, wir haben den folgenden Ordner und die folgenden Dateien. Hier ist mymodule.py identisch mit vorher und __init__.py ist eine leere Datei:

.
└── mypackage
    ├── __init__.py
    └── mymodule.py

Die Dateien __init__.py sind erforderlich, damit Python die Verzeichnisse als Pakete behandelt. Weitere Informationen finden Sie in der Dokumentation zu den Modulen, die später bereitgestellt werden.

Unser aktuelles Arbeitsverzeichnis befindet sich eine Ebene über dem gewöhnlichen Ordner namens mypackage

$ ls
mypackage

Wenn wir jetzt den Python3-Interpreter ausführen, können wir das Modul mymodule.py, das die erforderliche Funktion myfunc enthält, auf die folgende Weise importieren und ausführen (Sie würden normalerweise nur eine der folgenden Möglichkeiten wählen):

>>> import mypackage
>>> from mypackage import mymodule
>>> mymodule.myfunc()
Hello!
>>> import mypackage.mymodule
>>> mypackage.mymodule.myfunc()
Hello!
>>> from mypackage import mymodule
>>> mymodule.myfunc()
Hello!
>>> from mypackage.mymodule import myfunc
>>> myfunc()
Hello!
>>> from mypackage.mymodule import *
>>> myfunc()
Hello!

Unter der Annahme von Python 3 gibt es eine hervorragende Dokumentation unter: Modules

In Bezug auf die Namenskonventionen für Pakete und Module sind die allgemeinen Richtlinien in PEP-0008 angegeben - siehe Paket- und Modulnamen

Module sollten kurze, ausschließlich aus Kleinbuchstaben bestehende Namen haben. Unterstriche können im Modulnamen verwendet werden, wenn sie die Lesbarkeit verbessern. Python-Pakete sollten auch kurze, vollständige Namen haben, obwohl die Verwendung von Unterstrichen nicht empfohlen wird.




Sobald Sie Ihre ausgewählten Befehle definiert haben, können Sie die gespeicherte Datei einfach per Drag & Drop in den Lib-Ordner in Ihren Python-Programmdateien ziehen.

>>> import mymodule 
>>> mymodule.myfunc()