Jak napisać moduł/pakiet Pythona?
Tworzyłem Skrypty Pythona do prostych zadań w pracy i nigdy nie zawracałem sobie głowy pakowaniem ich dla innych. Teraz zostałem przydzielony do tworzenia wrappera Pythona dla REST API. Nie mam zielonego pojęcia jak zacząć i potrzebuję pomocy.
Co mam:
(po prostu chcę być konkretny, Jak to możliwe) mam virtualenv gotowe, jest również w github , the.istnieje również plik gitignore dla Pythona, Plus żądania biblioteka do interakcji z REST API. To wszystko.
Oto aktualne drzewo katalogów
.
├── bin
│ └── /the usual stuff/
├── include
│ └── /the usual stuff/
├── lib
│ └── python2.7
│ └── /the usual stuff/
├── local
│ └── /the usual stuff/
└── README.md
27 directories, 280 files
Nie wiem nawet, gdzie umieścić pliki. py, jeśli kiedykolwiek je zrobię.
Co chciałem zrobić:
Make a Python module install-able with " pip install ..."
Jeśli to możliwe, chcę ogólny krok po kroku proces pisania modułów Pythona.
7 answers
Moduł jest plikiem zawierającym definicje i instrukcje Pythona. Nazwa pliku jest nazwą modułu z przyrostkiem .py
Utwórz hello.py
a następnie napisz następującą funkcję jako jej zawartość:
def helloworld():
print "hello"
Następnie możesz zaimportować hello
:
>>> import hello
>>> hello.helloworld()
'hello'
>>>
Aby pogrupować wiele plików .py
umieść je w folderze. Każdy folder z __init__.py
jest uważany przez Pythona za moduł i można go nazwać pakietem
|-HelloModule
|_ __init__.py
|_ hellomodule.py
Możesz przejść do instrukcji importu w module Zwykle sposób.
Aby uzyskać więcej informacji, patrz 6.4. Pakiety .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-30 13:11:42
Python 3-zaktualizowano 18 listopada 2015
uznałem przyjętą odpowiedź za użyteczną, ale chciałem rozszerzyć kilka punktów z korzyścią dla innych na podstawie moich własnych doświadczeń.
Moduł: moduł jest plikiem zawierającym definicje i instrukcje Pythona. Nazwa pliku jest nazwą modułu z dołączonym sufiksem. py.
Przykład modułu: Załóżmy, że mamy pojedynczy skrypt Pythona w bieżącym katalogu, tutaj GO nazywam mymodule.py
Plik mymodule.py zawiera następujący kod:
def myfunc():
print("Hello!")
Jeśli uruchomimy interpreter python3 z bieżącego katalogu, możemy zaimportować i uruchomić funkcję myfunc w następujący sposób (zazwyczaj wystarczy wybrać jeden z następujących sposobów):
>>> import mymodule
>>> mymodule.myfunc()
Hello!
>>> from mymodule import myfunc
>>> myfunc()
Hello!
>>> from mymodule import *
>>> myfunc()
Hello!
Ok, to było dość łatwe.
Teraz Załóżmy, że musisz umieścić ten moduł we własnym dedykowanym folderze, aby zapewnić przestrzeń nazw modułów, zamiast uruchamiam go ad-hoc z bieżącego katalogu roboczego. W tym miejscu warto wyjaśnić pojęcie pakietu .
Package: pakiety są sposobem strukturyzacji przestrzeni nazw modułów Pythona za pomocą "kropkowanych nazw modułów". Na przykład, nazwa modułu A. b oznacza podmoduł o nazwie B w pakiecie o nazwie A. Tak jak użycie modułów pozwala autorom różnych modułów uniknąć martwienia się o globalne nazwy zmiennych, użycie modułu kropkowanego names pozwala autorom pakietów wielomodułowych, takich jak NumPy czy Python Imaging Library, nie martwić się o nazwy innych modułów.
Przykład pakietu : Załóżmy teraz, że mamy następujący folder i pliki. Tutaj, mymodule.py jest identyczna jak poprzednio, oraz _init__.py jest pustym plikiem:
.
└── mypackage
├── __init__.py
└── mymodule.py
The __init__.py pliki są wymagane, aby Python traktował katalogi jako zawierające Pakiety. Aby uzyskać więcej informacji, zapoznaj się z modułami link do dokumentacji podany później.
Nasz bieżący katalog roboczy znajduje się o jeden poziom powyżej zwykłego folderu o nazwie mypackage
$ ls
mypackage
Jeśli teraz uruchomimy interpreter python3, możemy zaimportować i uruchomić moduł mymodule.py zawierający wymaganą funkcję myfunc w następujący sposób (zazwyczaj wystarczy wybrać jedną z poniższych):
>>> 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!
Zakładając, że Python 3, istnieje doskonała dokumentacja w: Moduły
Jeśli chodzi o konwencje nazewnictwa pakietów i modułów, ogólne wytyczne podano w PEP-0008-zobacz nazwy pakietów i modułów
Moduły powinny mieć krótkie, pisane małymi literami nazwy. Podkreślniki mogą być użyte w nazwie modułu, jeśli poprawia to czytelność. Pakiety Pythona powinny również mieć krótkie, pisane małymi literami nazwy, chociaż nie zaleca się używania podkreślników.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-01 22:42:02
Ponieważ nikt jeszcze nie omówił tej kwestii OP:
Co chciałem zrobić:
Make a Python module install-able with " pip install ..."
Oto absolutny minimalny przykład, pokazujący podstawowe kroki przygotowania i przesłania pakietu do PyPI za pomocą setuptools
i twine
.
Nie jest to bynajmniej substytut czytania przynajmniej tutoriala, jest w nim znacznie więcej niż omówione w tym bardzo podstawowym przykład.
Tworzenie samego pakietu jest już objęte innymi odpowiedziami tutaj, więc załóżmy, że mamy ten krok objęty i strukturę naszego projektu w następujący sposób:]}
.
└── hellostackoverflow/
├── __init__.py
└── hellostackoverflow.py
Aby użyć setuptools
do pakowania, musimy dodać plik setup.py
, który trafi do folderu głównego naszego projektu:
.
├── setup.py
└── hellostackoverflow/
├── __init__.py
└── hellostackoverflow.py
Na minimum, określamy metadane dla naszego pakietu, nasz setup.py
wyglądałby tak:
from setuptools import setup
setup(
name='hellostackoverflow',
version='0.0.1',
description='a pip-installable package example',
license='MIT',
packages=['hellostackoverflow'],
author='Benjamin Gerfelder',
author_email='[email protected]',
keywords=['example'],
url='https://github.com/bgse/hellostackoverflow'
)
Ponieważ ustawiliśmy license='MIT'
, dołączamy kopię w naszym projekt jako LICENCE.txt
, obok pliku readme w reStructuredText jako README.rst
:
.
├── LICENCE.txt
├── README.rst
├── setup.py
└── hellostackoverflow/
├── __init__.py
└── hellostackoverflow.py
W tym momencie jesteśmy gotowi do rozpoczęcia pakowania za pomocą setuptools
, jeśli nie mamy go już zainstalowanego, możemy zainstalować go za pomocą pip
:
pip install setuptools
Aby to zrobić i utworzyć source distribution
, w głównym folderze naszego projektu wywołujemy naszą setup.py
z linii poleceń, określając, że chcemy sdist
:
python setup.py sdist
Spowoduje to utworzenie naszego pakietu dystrybucyjnego i egg-info, a rezultatem będzie struktura folderów jak to, z naszym pakietem w dist
:
.
├── dist/
├── hellostackoverflow.egg-info/
├── LICENCE.txt
├── README.rst
├── setup.py
└── hellostackoverflow/
├── __init__.py
└── hellostackoverflow.py
W tym momencie mamy pakiet, który możemy zainstalować używając pip
, więc z naszego katalogu głównego projektu (zakładając, że masz wszystkie nazwy, jak w tym przykładzie):
pip install ./dist/hellostackoverflow-0.0.1.tar.gz
Jeśli wszystko pójdzie dobrze, możemy teraz otworzyć interpreter Pythona, powiedziałbym, że gdzieś poza naszym katalogiem projektu, aby uniknąć nieporozumień i spróbować użyć naszego nowego pakietu: {]}
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 hellostackoverflow import hellostackoverflow
>>> hellostackoverflow.greeting()
'Hello Stack Overflow!'
Teraz, gdy potwierdziliśmy, że pakiet instaluje się i działa, możemy go przesłać do PyPI.
[30]} ponieważ nie chcemy zanieczyszczać repozytorium naszymi eksperymentami, tworzymy konto dla repozytorium testowego {45]} i instalujemytwine
dla procesu wysyłania: {[31]]}
pip install twine
Teraz jesteśmy już prawie na miejscu, z założonym kontem po prostu mówimy twine
, aby przesłać nasz pakiet, poprosi o nasze poświadczenia i przesłać nasz pakiet DO OKREŚLONEGO repozytorium:
twine upload --repository-url https://test.pypi.org/legacy/ dist/*
Możemy teraz zalogować się na nasze konto w repozytorium testów PyPI i podziwiać nasze w tym celu należy pobrać pakiet, a następnie pobrać go za pomocą pip
:
pip install --index-url https://test.pypi.org/simple/ hellostackoverflow
Jak widać, podstawowy proces nie jest zbyt skomplikowany. Jak powiedziałem wcześniej, jest to o wiele więcej niż omówione tutaj, więc śmiało i przeczytaj samouczek aby uzyskać bardziej szczegółowe wyjaśnienie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-15 01:57:40
Po zdefiniowaniu wybranych poleceń, możesz po prostu przeciągnąć i upuścić zapisany plik do folderu Lib w plikach programu Pythona.
>>> import mymodule
>>> mymodule.myfunc()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-15 11:54:54
Stworzyłem projekt, aby łatwo zainicjować szkielet projektu od podstaw. https://github.com/MacHu-GWU/pygitrepo-project .
I możesz stworzyć projekt testowy, powiedzmy, learn_creating_py_package
.
Możesz dowiedzieć się, jaki komponent powinieneś mieć do różnych celów, takich jak:
- create virtualenv
- zainstaluj się
- Uruchom unittest
- Uruchom pokrycie kodu
- dokument budowy
- dokument
- Uruchom unittest w innej wersji Pythona
- deploy to PYPI
Zaletą używania pygitrepo
jest to, że te żmudne są automatycznie tworzone i dostosowywane do Twoich package_name
, project_name
, github_account
, document host service
, windows or macos or linux
.
Jest to dobre miejsce, aby nauczyć się rozwijać projekt Pythona jak profesjonalista.
Mam nadzieję, że to pomoże. Dziękuję.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-02 02:42:03
Stwórz plik o nazwie "hello.py"
Jeśli używasz Pythona 2.x
def func():
print "Hello"
Jeśli używasz Pythona 3.x
def func():
print("Hello")
Uruchom plik. Następnie możesz spróbować:
>>> import hello
>>> hello.func()
Hello
Jeśli chcesz trochę mocno, możesz użyć następującego:
Jeśli używasz Pythona 2.x
def say(text):
print text
Jeśli używasz Pythona 3.x
def say(text):
print(text)
Widzisz ten w nawiasie obok define? To ważne. Jest to ten, który można wykorzystać w ramach zdefiniuj.
Tekst - możesz go użyć, gdy chcesz, aby program mówił to, co chcesz. Zgodnie z nazwą jest to tekst. Mam nadzieję, że wiesz, co oznacza tekst. Oznacza "słowa" lub "zdania".
Uruchom plik. Następnie możesz wypróbować następujące opcje, jeśli używasz Pythona 3.x:
>>> import hello
>>> hello.say("hi")
hi
>>> from hello import say
>>> say("test")
test
Dla Pythona 2.x-chyba to samo z Pythonem 3? Nie mam pojęcia. Popraw mnie, jeśli popełniłem błąd w Pythonie 2.x (znam Pythona 2, ale jestem używany z Pythonem 3)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-20 17:44:33
Moduł jest plikiem zawierającym definicje i instrukcje Pythona. Nazwa pliku jest nazwą modułu z przyrostkiem. py
Utwórz plik o nazwie hello.py z następującą funkcją jako zawartością:
def helloworld():
print "hello"
Wtedy możesz
import hello
hello.helloworld()
Aby pogrupować wiele plików .py, umieść je w folderze. Każdy folder z init . py jest uważany przez Pythona za moduł i można go nazwać pakietem.
|-HelloModule |_ init . py / align = "left" / hellomodule.py
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-23 00:03:41