Jak napisać moduł / pakiet Python?

375

Tworzę skrypty Pythona do prostych zadań w pracy i nigdy tak naprawdę nie zawracałem sobie głowy pakowaniem ich do użycia przez innych. Teraz przydzielono mi zadanie tworzenia otoki Pythona dla interfejsu API REST. Nie mam pojęcia, jak zacząć i potrzebuję pomocy.

Co ja mam:

(Chcę być konkretny, jak to możliwe) Mam gotową virtualenv , jest ona również uruchomiona w github , plik .gitignore dla Pythona jest tam również, a także biblioteka żądań do interakcji z interfejsem API REST. Otóż ​​to.

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

Nawet nie wiem, gdzie umieścić pliki .py, jeśli kiedykolwiek je utworzę.

Co chciałem zrobić:

Uczyń moduł Pythona instalowalnym za pomocą „pip install ...”

Jeśli to możliwe, chcę ogólny proces krok po kroku podczas pisania modułów Python.

yowmamasita
źródło
15
Zacznę od rozdziału 6 samouczka (2.7) lub tutaj, aby znaleźć 3.x Przeszukaj Internet w poszukiwaniu samouczka modułu python, a znajdziesz wiele innych.
Roland Smith
6
Nikt nie odpowiedział na pip
whackamadoodle3000
github.com/MacHu-GWU/pygitrepo-project ta biblioteka pomaga tworzyć szkielet projektu od zera, a potrzebna funkcja jest od razu po wyjęciu z pudełka.
MacSanhe,

Odpowiedzi:

424

Moduł to plik zawierający definicje i instrukcje w języku Python. Nazwa pliku to nazwa modułu z sufiksem.py

Utwórz hello.pynastępnie napisz następującą funkcję jako jej treść:

def helloworld():
   print "hello"

Następnie możesz zaimportować hello:

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

Aby zgrupować wiele .pyplików, umieść je w folderze. Każdy folder z an __init__.pyjest uważany przez moduł za moduł i możesz nazwać go pakietem

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

Możesz przejść do instrukcji importowania w swoim module w zwykły sposób.

Aby uzyskać więcej informacji, zobacz 6.4. Pakiety .

Anuj
źródło
7
czy to byłby ostatni: z HellowModule import hellomodule? Czy to może być witam w folderze modułu, więc byłoby z HelloModule import hello
nycynik
Obecnie bawię się Pythonem i ta odpowiedź musi być jedną z najbardziej pomocnych, na jakie się natknąłem. Wyjaśnia to bardzo dobrze, dziękuję.
Darren Wainwright
polecenie „pip install” nie zadziała, musisz też być w tym samym katalogu, aby go użyć
Math Coder 101
234

Python 3 - AKTUALIZACJA 18 listopada 2015

Uznałem, że przyjęta odpowiedź jest przydatna, ale chciałem rozwinąć kilka punktów z korzyścią dla innych w oparciu o moje własne doświadczenia.

Moduł: Moduł to plik zawierający definicje i instrukcje w języku Python. Nazwa pliku to nazwa modułu z dołączonym przyrostkiem .py.

Przykład modułu : Załóżmy, że mamy pojedynczy skrypt Pythona w bieżącym katalogu, tutaj nazywam go 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 na następujące różne sposoby (zazwyczaj wystarczy wybrać jeden z poniższych):

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

Ok, więc to było dość łatwe.

Załóżmy teraz, że musisz umieścić ten moduł we własnym dedykowanym folderze, aby zapewnić przestrzeń nazw modułu, zamiast uruchamiać go ad-hoc z bieżącego katalogu roboczego. W tym miejscu warto wyjaśnić koncepcję pakietu .

Pakiet : Pakiety są sposobem strukturyzacji przestrzeni nazw modułów Pythona za pomocą „kropkowanych nazw modułów”. Na przykład nazwa modułu AB oznacza podmoduł o nazwie B w pakiecie o nazwie A. Podobnie jak użycie modułów oszczędza autorom różnych modułów od konieczności martwienia się o globalne nazwy zmiennych, użycie kropkowanych nazw modułów oszczędza autorów pakietów wielomodułowych, takich jak NumPy lub Python Imaging Library, nie muszą się martwić o nazwy swoich modułów.

Przykład pakietu : Załóżmy teraz, że mamy następujący folder i pliki. Tutaj mymodule.py jest identyczny jak poprzednio, a __init__.py jest pustym plikiem:

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

Pliki __init__.py są wymagane, aby Python traktował katalogi jako zawierające pakiety. Więcej informacji można znaleźć w linku do dokumentacji modułów podanym później.

Nasz aktualny 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 na następujące różne sposoby (zazwyczaj wystarczy wybrać jeden 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 na: Moduły

Jeśli chodzi o konwencje nazewnictwa dla pakietów i modułów, ogólne wytyczne podano w PEP-0008 - patrz Nazwy pakietów i modułów

Moduły powinny mieć krótkie, małe litery. W nazwie modułu można zastosować podkreślenia, jeśli poprawi to czytelność. Pakiety Python powinny także mieć krótkie, małe litery, chociaż odradza się stosowanie znaków podkreślenia.

arcseldon
źródło
5
Ładne proste wyjaśnienie. Co jeśli chcesz zachować inny folder w moim pakiecie?
Anuj Gupta,
3
Dołączenie zależy całkowicie od tego, co napisałeś. W przypadku, gdy umieścisz rzeczy poza funkcją w swoim module, uruchomisz je podczas wywołania like import mypackage. W przypadku, gdy chcesz zaimportować tylko funkcję z modułu (nawet pliku), lepiej użyć from module import function. W przypadku podfolderu from subfolder.module import function, który można po prostu wywołać function()bez wyzwalania innych części kodu. Nie używaj również, from module import *jeśli tak naprawdę nie potrzebujesz.
m3nda
5
Pozostaje tylko pytanie, w jaki sposób mogę uzyskać pakiet, aby zaimportować wszystko import mypackage? Dodawanie import mymoduledo __init__.pynie działa.
576i
Staranne wyjaśnienie! Mam jednak pytanie, czy numpy jest pakietem, w jaki sposób mogę wykonać numpy.cos (1) w moim tłumaczu, ponieważ wydaje się, że nazwa modułu między nimi zaginęła. Nie?
user1935724
3
Co powiesz na pip?
whackamadoodle3000,
199

Ponieważ nikt jeszcze nie omówił tego pytania PO:

Co chciałem zrobić:

Uczyń moduł Pythona instalowalnym za pomocą „pip install ...”

Oto absolutnie minimalny przykład, pokazujący podstawowe kroki przygotowania i przesłania pakietu do PyPI przy użyciu setuptoolsi twine.

W żadnym wypadku nie jest to substytut czytania co najmniej samouczka , jest o wiele więcej niż w tym bardzo podstawowym przykładzie.

Samo tworzenie pakietu jest już objęte innymi odpowiedziami, więc załóżmy, że omówiliśmy ten krok i naszą strukturę projektu w następujący sposób:

.
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

Aby użyć setuptoolsdo pakowania, musimy dodać plik setup.py, który trafi do folderu głównego naszego projektu:

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

Jako minimum określamy metadane dla naszego pakietu, setup.pywyglądałoby to 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'
)

Odkąd ustawiliśmy license='MIT', dołączamy kopię do naszego projektu jako LICENCE.txtwraz z plikiem readme w reStructuredText jako README.rst:

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

W tym momencie jesteśmy gotowi, aby rozpocząć pakowanie 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 folderze głównym naszego projektu wywołujemy nasz setup.pyz wiersza poleceń, określając, że chcemy sdist:

python setup.py sdist

Spowoduje to utworzenie naszego pakietu dystrybucyjnego i informacji o jajku, i spowoduje powstanie takiej struktury folderów, 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ć 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óbuj użyć naszego nowego błyszczącego 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!'

Po potwierdzeniu, że pakiet instaluje się i działa, możemy przesłać go do PyPI.

Ponieważ nie chcemy zanieczyszczać repozytorium na żywo za pomocą naszych eksperymentów, tworzymy konto dla repozytorium testowego i instalujemy twinedla procesu przesyłania:

pip install twine

Teraz jesteśmy już prawie gotowi, z utworzonym kontem po prostu mówimy, twineaby przesłać nasz pakiet, poprosi on o nasze poświadczenia i prześle 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 przez chwilę podziwiać świeżo przesłany 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 bardzo skomplikowany. Jak powiedziałem wcześniej, jest o wiele więcej niż tu omówione, więc czytaj dalej samouczek, aby uzyskać bardziej szczegółowe wyjaśnienia.

bgse
źródło
Czy moja paczka zostanie opublikowana zaraz po tym setuptools?
U10 - Napastnik
@ U9-Forward Nie, publikowanie jest zakończone twine, ale możesz przetestować pakiet lokalnie przed opublikowaniem po utworzeniu go setuptools.
bgse
9

Po zdefiniowaniu wybranych poleceń możesz po prostu przeciągnąć i upuścić zapisany plik do folderu Lib w plikach programu python.

>>> import mymodule 
>>> mymodule.myfunc()
Dreamatronix
źródło
2

Utwórz plik o nazwie „hello.py”

Jeśli używasz Python 2.x

def func():
    print "Hello"

Jeśli używasz języka Python 3.x

def func():
    print("Hello")

Uruchom plik. Następnie możesz wypróbować następujące czynności:

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

Jeśli chcesz trochę ciężko, możesz użyć następujących opcji:

Jeśli używasz Python 2.x

def say(text):
    print text

Jeśli używasz języka Python 3.x

def say(text):
    print(text)

Widzisz ten w nawiasie obok definicji? To jest ważne. Jest to ten, którego można użyć w definicji.

Tekst - możesz go użyć, gdy chcesz, aby program mówił 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 czynności, jeśli używasz języka Python 3.x:

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

W przypadku Python 2.x - Myślę, że to samo z Python 3? Brak pomysłu. Popraw mnie, jeśli popełniłem błąd w Pythonie 2.x (znam Python 2, ale używam go w Pythonie 3)

Kakkoiikun
źródło
2

Stworzyłem projekt, aby łatwo zainicjować szkielet projektu od zera . https://github.com/MacHu-GWU/pygitrepo-project .

I można utworzyć projekt testowy, powiedzmy Powiedzmy, learn_creating_py_package.

Możesz dowiedzieć się, jaki komponent powinieneś mieć do różnych celów, takich jak :

  • utwórz virtualenv
  • zainstalować się
  • biec niespokojnie
  • uruchomić zasięg kodu
  • skompiluj dokument
  • wdrożyć dokument
  • uruchomić unittest w innej wersji Pythona
  • wdrożyć w PYPI

Zaletą stosowania pygitrepojest to, że te uciążliwe są tworzone automatycznie się i dostosować package_name, project_name, github_account, document host service, windows or macos or linux.

Jest to dobre miejsce do nauki rozwoju projektu pythonowego jak profesjonalista.

Mam nadzieję, że to może pomóc.

Dziękuję Ci.

MacSanhe
źródło