Slovak (Slovenčina) translation by Ryan (you can also view the original English article)
Python je skvelý programovací jazyk, ale balíčkovanie je jedným z najslabších článkov. Je to medzi komunitou dosť známy fakt. Proces inštalácie, importovania, používania a tvorby balíčkov sa za posledné roky ohromne zlepšil, ale ešte stále sa nevyrovná novším jazykom ako je Go alebo Rust.
V tomto návode si naučíme všetko, čo potrebujete vedieť o písaní, balení a distribúcii vašich balíčkov.
Ako napísať knižnicu v Pythone
Knižnica je kolekcia niekoľkých modulov, ktoré sú zabalené do jedného balíčka. To znamená, že všetky tieto moduly sú v jednom priečinku, ktoré Python vyhľadáva.
Napíšme si malý balíček v Pythone, aby sme si predstavili tento koncept.
Balíček Pathology
Python 3 má skvelý objekt Path, ktorý je ohromne lepší oproti modulu os.path v Pythone 2. Ale chýba tomu jedna dôležitá funkcia—vyhľadávanie cesty na vybraný skript. To je veľmi dôležité, keď chcete nájsť súbory relatívne k vybranému skriptu.
Vo väčšine prípadov skript môže byť nainštalovaný v akomkoľvek umiestnení, takže nemôžete používať absolútne cesty. Názov projektu je ľubovoľný, takže nemôžete používať ani relatívne cesty. Keď chcete sa dostať do podpriečinka, musíte zistiť cestu k súčasnému priečinku.
Pozrite sa, ako sa to robí v Pythone:
import pathlib script_dir = pathlib.Path(__file__).parent.resolve()
Keď sa chcete dostať k súboru "file.txt", ktorý sa nachádza v podpriečinku "data", môžete použiť tento kód: print(open(str(script_dir/'data/file.txt').read())
Pomocou balíčka pathology môžete použiť metódu script_dir:
from pathology.Path import script_dir print(open(str(script_dir()/'data/file.txt').read())
Balíček pathology je veľmi jednoduchý. Vytvorí vlastnú triedu Path z balíčka pathlib a pridá statickú metódu script_dir(), ktorá vráti cestu k volanému skriptu.
Implementácia:
import pathlib import inspect class Path(type(pathlib.Path())): @staticmethod def script_dir(): print(inspect.stack()[1].filename) p = pathlib.Path(inspect.stack()[1].filename) return p.parent.resolve()
Kvôli multi-platformovej implementácií pathlib.Path môžete derivovať priamo z tej triedy, ktorá rozširuje špecifickú podtriedu (PosixPath alebo WindowsPath). Rezolúcia priečinka skriptu využíva modul inspect, ktorý vyhľadáva funkciu, ktorá ten modul vyvoláva a jej atribút súbora.
Testovanie balíčka
Keď vytvárate niečo viac, než nejaký jednorázový skript, mali by ste ho otestovať. Modul pathology nie je žiadnou výnimkou. Toto sú testy vytvorené pomocou štandardného unit testing frameworku:
import os import shutil from unittest import TestCase from pathology.path import Path class PathTest(TestCase): def test_script_dir(self): expected = os.path.abspath(os.path.dirname(__file__)) actual = str(Path.script_dir()) self.assertEqual(expected, actual) def test_file_access(self): script_dir = os.path.abspath(os.path.dirname(__file__)) subdir = os.path.join(script_dir, 'test_data') if Path(subdir).is_dir(): shutil.rmtree(subdir) os.makedirs(subdir) file_path = str(Path(subdir)/'file.txt') content = '123' open(file_path, 'w').write(content) test_path = Path.script_dir()/subdir/'file.txt' actual = open(str(test_path)).read() self.assertEqual(content, actual)
Path v Pythone
Balíčky v Pythone musia byť nainštalované vo vyhľadavanej ceste, aby mohli byť importované modulmi v Pythone. Vyhľadávaná cesta je zoznam priečinkov a je dostupná v sys.path
: Toto je môj súčasný sys.path:
>>> print('\n'.join(sys.path)) /Users/gigi.sayfan/miniconda3/envs/py3/lib/python36.zip /Users/gigi.sayfan/miniconda3/envs/py3/lib/python3.6 /Users/gigi.sayfan/miniconda3/envs/py3/lib/python3.6/lib-dynload /Users/gigi.sayfan/miniconda3/envs/py3/lib/python3.6/site-packages /Users/gigi.sayfan/miniconda3/envs/py3/lib/python3.6/site-packages/setuptools-27.2.0-py3.6.egg
Vedzte, že prvý prázdny riadok reprezentuje priečinok, na ktorom bol tento skript spustený. Moduly môžete importovať z priečinkov vypísaných vyššie. Taktiež môžete pridávať alebo odstraňovať priečinky do/zo sys.path.
Taktiež môžete použiť premennú PYTHONPATH alebo jednu z iných možností. Balíčky zo site-packages
sú štandardne zahrnuté, pretože sa tam inštalujú balíčky pomocou pip.
Ako zabaliť knižnicu
Teraz, keď máme napísaný kód a testy, teraz ich môžeme zabaliť do knižnice. Cez Python sa to dá jednoducho pomocou modulu setup. Vytvorte súbor s názvom setup.py v hlavnom priečinku knižnice. Pre vytvorenie zdrojovej distribúcie, spustite: python setup.py sdist
Pre vytvorenie binárnej distribúcie, spustite: python setup.py bdist_wheel
Toto je súbor setup.py balíčka pathology:
from setuptools import setup, find_packages setup(name='pathology', version='0.1', url='https://github.com/the-gigi/pathology', license='MIT', author='Gigi Sayfan', author_email='the.gigi@gmail.com', description='Add static script_dir() method to Path', packages=find_packages(exclude=['tests']), long_description=open('README.md').read(), zip_safe=False)
Obsahuje dosť metadát spolu s položkou "packages", ktorá používa funkciu find_packages()
importovanú zo setuptools
k nájdeniu podbalíčkov
Teraz vytvoríme zdrojovú distribúciu:
$ python setup.py sdist running sdist running egg_info creating pathology.egg-info writing pathology.egg-info/PKG-INFO writing dependency_links to pathology.egg-info/dependency_links.txt writing top-level names to pathology.egg-info/top_level.txt writing manifest file 'pathology.egg-info/SOURCES.txt' reading manifest file 'pathology.egg-info/SOURCES.txt' writing manifest file 'pathology.egg-info/SOURCES.txt' warning: sdist: standard file not found: should have one of README, README.rst, README.txt running check creating pathology-0.1 creating pathology-0.1/pathology creating pathology-0.1/pathology.egg-info copying files to pathology-0.1... copying setup.py -> pathology-0.1 copying pathology/__init__.py -> pathology-0.1/pathology copying pathology/path.py -> pathology-0.1/pathology copying pathology.egg-info/PKG-INFO -> pathology-0.1/pathology.egg-info copying pathology.egg-info/SOURCES.txt -> pathology-0.1/pathology.egg-info copying pathology.egg-info/dependency_links.txt -> pathology-0.1/pathology.egg-info copying pathology.egg-info/not-zip-safe -> pathology-0.1/pathology.egg-info copying pathology.egg-info/top_level.txt -> pathology-0.1/pathology.egg-info Writing pathology-0.1/setup.cfg creating dist Creating tar archive removing 'pathology-0.1' (and everything under it)
Upozornilo ma, že používam neštandardný súbor README.md. Toto upozornenie sa dá bezpečne ignorovať. Výsledkom je tar.gz súbor pod priečinkom dist:
$ ls -la dist total 8 drwxr-xr-x 3 gigi.sayfan gigi.sayfan 102 Apr 18 21:20 . drwxr-xr-x 12 gigi.sayfan gigi.sayfan 408 Apr 18 21:20 .. -rw-r--r-- 1 gigi.sayfan gigi.sayfan 1223 Apr 18 21:20 pathology-0.1.tar.gz
A tu je binárna distribúcia:
$ python setup.py bdist_wheel running bdist_wheel running build running build_py creating build creating build/lib creating build/lib/pathology copying pathology/__init__.py -> build/lib/pathology copying pathology/path.py -> build/lib/pathology installing to build/bdist.macosx-10.7-x86_64/wheel running install running install_lib creating build/bdist.macosx-10.7-x86_64 creating build/bdist.macosx-10.7-x86_64/wheel creating build/bdist.macosx-10.7-x86_64/wheel/pathology copying build/lib/pathology/__init__.py -> build/bdist.macosx-10.7-x86_64/wheel/pathology copying build/lib/pathology/path.py -> build/bdist.macosx-10.7-x86_64/wheel/pathology running install_egg_info running egg_info writing pathology.egg-info/PKG-INFO writing dependency_links to pathology.egg-info/dependency_links.txt writing top-level names to pathology.egg-info/top_level.txt reading manifest file 'pathology.egg-info/SOURCES.txt' writing manifest file 'pathology.egg-info/SOURCES.txt' Copying pathology.egg-info to build/bdist.macosx-10.7-x86_64/wheel/pathology-0.1-py3.6.egg-info running install_scripts creating build/bdist.macosx-10.7-x86_64/wheel/pathology-0.1.dist-info/WHEEL
Balíček pathology obsahuje iba čisté Python moduly, takže môže byť vytvorený aj univerzálny balíček. Ak váš balíček obsahuje aj rozšírenia v jazyku C, musíte vytvoriť samostatný balíček pre každú platformu:
$ ls -la dist total 16 drwxr-xr-x 4 gigi.sayfan gigi.sayfan 136 Apr 18 21:24 . drwxr-xr-x 13 gigi.sayfan gigi.sayfan 442 Apr 18 21:24 .. -rw-r--r-- 1 gigi.sayfan gigi.sayfan 2695 Apr 18 21:24 pathology-0.1-py3-none-any.whl -rw-r--r-- 1 gigi.sayfan gigi.sayfan 1223 Apr 18 21:20 pathology-0.1.tar.gz
Keď chcete vedieť viac o balíčkovaní knižníc v Pythone, pozrite Ako písať vlastné balíčky v Pythone.
Ako distribuovať balíček
Python má centrálny repozitár balíčkov nazvaný PyPI (Python Packages Index). Keď inštalujete balíček pomocou pip, pip ho stiahne z PyPI (pokiaľ neurčite iný repozitár). Aby sme distribuovali náš balíček pathology, potrebujeme ho odovzdať do PyPI a pridať k tomu nejaké metadáta, ktoré PyPI vyžaduje. Postupujte podľa týchto krokov:
- Vytvorte si účet na PyPI (iba raz).
- Zaregistrujte váš balíček.
- Odovzdajte váš balíček.
Vytvorenie účtu
Účet môžete vytvoriť na stránkach PyPI. Potom vytvorte súbor .pypirc vo vašom domácom priečinku:
[distutils] index-servers=pypi [pypi] repository = https://pypi.python.org/pypi username = the_gigi
Pre účely testovania môžeme pridať server "pypitest" do súbora .pypirc:
[distutils] index-servers= pypi pypitest [pypitest] repository = https://testpypi.python.org/pypi username = the_gigi [pypi] repository = https://pypi.python.org/pypi username = the_gigi
Registrácia balíčka
Ak toto je prvé vydanie vašeho balíčka, potrebujete ho zaregistrovať pomocou PyPI. Použite príkaz register súbora setup.py. Vedzte, že to budem vydávať na testovací repozitár:
$ python setup.py register -r pypitest running register running egg_info writing pathology.egg-info/PKG-INFO writing dependency_links to pathology.egg-info/dependency_links.txt writing top-level names to pathology.egg-info/top_level.txt reading manifest file 'pathology.egg-info/SOURCES.txt' writing manifest file 'pathology.egg-info/SOURCES.txt' running check Password: Registering pathology to https://testpypi.python.org/pypi Server response (200): OK
Odovzdanie balíčka
Kedže je už balíček zaregistrovaný, môžeme ho odovzdať. Odporúčam použiť twine, pretože je bezpečnejší. Nainštalujte ho pomocou pip install twine
. Potom odovzdajte váš balíček pomocou twine a určite jeho heslo (ktoré je v tomto útržku zakryté):
$ twine upload -r pypitest -p <redacted> dist/* Uploading distributions to https://testpypi.python.org/pypi Uploading pathology-0.1-py3-none-any.whl [================================] 5679/5679 - 00:00:02 Uploading pathology-0.1.tar.gz [================================] 4185/4185 - 00:00:01
Keď chcete vedieť viac o distribúcii balíčkov, pozrite Ako zdieľať vaše balíčky napísané v Pythone
Záver
V tomto návode sme sa pozreli na celý proces písania balíčka v Pythone, balenia a distribúcie pomocou PyPI. Teraz by ste mali mať všetky nástroje k písaniu a zdieľaniu vašich knižníc do sveta.
Navyše, neváhajte a pozrite sa, čo máme k dispozícii v obchode a opýtajte sa pomocou komentárov dole.