Python är ett bra programmeringsspråk, men förpackningar är en av de svagaste punkterna. Det är ett välkänt faktum i samhället. Installera, importera, använda och skapa paket har förbättrats mycket under årens lopp, men det är fortfarande inte i nivå med nyare språk som Go and Rust som lärde mig mycket av Pythons och andra mogna språk.
I denna handledning lär du dig allt du behöver veta om att skriva, förpacka och distribuera dina egna paket.
Ett Python-bibliotek är en sammanhängande samling Python-moduler som är organiserad som ett Python-paket. I allmänhet betyder det att alla moduler lever under samma katalog och att den här katalogen finns på Pythons sökväg.
Låt oss skriva ett litet Python 3-paket och illustrera alla dessa begrepp.
Python 3 har ett utmärkt Path-objekt, vilket är en enorm förbättring jämfört med Python 2s obekväma os.path-modul. Men det saknas en viktig förmåga att hitta sökvägen för det aktuella skriptet. Detta är mycket viktigt när du vill hitta åtkomstfiler i förhållande till det aktuella skriptet.
I många fall kan skriptet installeras på vilket som helst ställe, så du kan inte använda absoluta vägar, och arbetskatalogen kan ställas in till valfritt värde, så du kan inte använda en relativ sökväg. Om du vill komma åt en fil i en underkatalog eller förlagskatalog måste du kunna räkna ut den aktuella skriptkatalogen.
Så här gör du det i Python:
import pathlib script_dir = pathlib.Path (__ file __). parent.resolve ()
För att komma åt en fil som heter "file.txt" i en "data" -underkatalog i det aktuella skriptets katalog kan du använda följande kod: print (open (str (script_dir / "data / file.txt). read ())
Med patologipaketet har du en inbyggd script_dir metod, och du använder den så här:
från pathology.Path import script_dir print (öppen (str (script_dir () / 'data / file.txt') .läs ())
Ja, det är en munnen. Patologipaketet är väldigt enkelt. Den härleder sin egen banklass från banlöpets väg och lägger till en statisk script_dir () som alltid returnerar sökvägen för uppringningsskriptet.
Här är genomförandet:
import pathlib import inspektera klassvägen (typ (pathlib.Path ())): @staticmethod def script_dir (): print (inspect.stack () [1] .filnamn) p = pathlib.Path (inspect.stack () [1 ] .filnamn) returnera p.parent.resolve ()
På grund av plattformsimplementeringen av pathlib.Path, du kan härleda direkt från det och måste härledas från en viss underklass (PosixPath eller WindowsPath). Skriptdirupplösningen använder inspektionsmodulen för att hitta den som ringer och sedan dess filnamnsattribut.
När du skriver något som är mer än ett kasta skript, bör du testa det. Patologimodulen är inget undantag. Här är testen med hjälp av standardenhetstestramen:
Importera oss Importera shutdown från unittest Import TestCase från 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 ()) själv.assertEqual (förväntad, faktisk) def test_file_access (egen): script_dir = os.path.abspath (os.path.dirname (__ file__)) subdir = os.path.join (script_dir, "test_data") om sökväg (subdir) .is_dir (): shutil.rmtree (subdir) os.makedirs (subdir) file_path = str (Path (subdir) / 'file.txt') content = '123' öppen (file_path, 'w') (innehåll) test_path = Path.script_dir () / subdir / 'file.txt' actual = open (str (test_path)) .läs () self.assertEqual (innehåll, faktiskt)
Python-paket måste installeras någonstans på Python-sökvägen som ska importeras av Python-moduler. Python sökvägen är en lista över kataloger och finns alltid tillgänglig i sys.path
. Här är min nuvarande sys.path:
>>> skriv ut ('\ 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/ Användare / gigi.sayfan / miniconda3 / envs / py3 / lib / python3.6 / site-paket / setuptools-27.2.0-py3.6.egg
Observera att den första tomma raden i utgången representerar den aktuella katalogen, så att du kan importera moduler från den aktuella arbetsmappen, oavsett vad den är. Du kan direkt lägga till eller ta bort kataloger till / från sys.path.
Du kan också definiera a PYTHON miljövariabel, och det finns några andra sätt att kontrollera det. Standarden site-paket
ingår som standard, och det är här paket du installerar med hjälp av pip go.
Nu när vi har vår kod och tester, låt oss paketera allt till ett korrekt bibliotek. Python ger ett enkelt sätt via installationsmodulen. Du skapar en fil som heter setup.py i paketets rotkatalog. Sedan, för att skapa en källdistribution kör du: python setup.py sdist
För att skapa en binär fördelning som heter ett hjul kör du: python setup.py bdist_wheel
Här är setup.py-filen i patologipaketet:
från setuptools import setup, hitta_packages setup (namn = 'pathology', version = "0.1", url = "https://github.com/the-gigi/pathology", licens = "MIT", författare = "Gigi Sayfan" , author_email = "[email protected]", description = "Lägg till statisk script_dir () -metod till sökväg", paket = find_packages (exclude = ['tests']), long_description = open ('README.md'). läs (), zip_safe = False)
Den innehåller en hel del metadata utöver det "paket" objektet som använder find_packages ()
funktion importerad från setuptools
att hitta delpaket.
Låt oss bygga en källdistribution:
$ python setup.py sdist körning sdist körning egg_info skapa pathology.egg-info skriva pathology.egg-info / PKG-INFO skriva dependency_links till pathology.egg-info / dependency_links.txt skriver högsta namn till pathology.egg-info / top_level.txt skriv manifestfilen 'pathology.egg-info / SOURCES.txt' läs manifestfilen 'pathology.egg-info / SOURCES.txt' skriv manifestfilen 'pathology.egg-info / SOURCES.txt' varning: sdist: standard filen hittades inte: borde ha en README, README.rst, README.txt körkontroll, skapa patologi-0.1 skapa patologi-0.1 / patologi skapa patologi-0.1 / pathology.egg-info kopiera filer till patologi-0.1 ... kopiering setup.py -> patologi-0,1 kopiering patologi / __ init__.py -> patologi-0.1 / patologi kopiering patologi / path.py -> patologi-0.1 / patologi kopiering pathology.egg-info / PKG-INFO -> patologi-0.1 / pathology.egg -info kopiering pathology.egg-info / SOURCES.txt -> patologi-0.1 / pathology.egg-info kopiering pathology.egg-info / dependency_links.txt -> patologi -0.1 / pathology.egg-info kopiering pathology.egg-info / non-zip-safe -> patologi-0.1 / pathology.egg-info kopiering pathology.egg-info / top_level.txt -> patologi-0.1 / pathology.egg -info Skrivarpatologi-0.1 / setup.cfg skapa dist Skapa tarararkiv som tar bort 'pathology-0.1' (och allt under det)
Varningen är för att jag använde en icke-standardiserad README.md-fil. Det är säkert att ignorera. Resultatet är en tar-gzipped-fil under dist-katalogen:
$ ls -la dist totalt 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
Och här är en binär fördelning:
$ python setup.py bdist_wheel kör bdist_wheel kör bygga springa build_py skapa bygga skapa build / lib skapa bygg / lib / patologi kopiering patologi / __ init__.py -> bygga / lib / patologi kopiering patologi / path.py -> bygga / lib / patologi installera för att bygga / bdist.macosx-10.7-x86_64 / hjulkörning installera kör install_lib skapa build / bdist.macosx-10.7-x86_64 skapa build / bdist.macosx-10.7-x86_64 / hjul skapa build / bdist.macosx-10.7-x86_64 / kopi / lib / patologi / __ init__.py -> bygg / bdist.macosx-10.7-x86_64 / hjul / patologi kopiering bygg / lib / patologi / path.py -> build / bdist.macosx-10.7-x86_64 / hjul / patologi kör install_egg_info körning egg_info skriftlig pathology.egg-info / PKG-INFO skriver dependency_links till pathology.egg-info / dependency_links.txt skriver toppnivå namn till pathology.egg-info / top_level.txt läs manifestfil 'patologi. ägg-info / SOURCES.txt "skriv manifest fil" pathology.egg-info / SOURCES.txt "Kopiering pathology.egg-info till bui ld / bdist.macosx-10.7-x86_64 / hjul / patologi-0.1-py3.6.egg-info kör install_scripts skapa build / bdist.macosx-10.7-x86_64 / hjul / patologi-0.1.dist-info / WHEEL
Patologipaketet innehåller bara rena Python-moduler, så ett universellt paket kan byggas. Om ditt paket innehåller C-förlängningar måste du bygga ett separat hjul för varje plattform:
$ ls -la dist totalt 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 patologi-0.1-py3-none-any .whl -rw-r - r-- 1 gigi.sayfan gigi.sayfan 1223 apr 18 21:20 patologi-0.1.tar.gz
För en djupare dyka in i ämnet för att förpacka Python-bibliotek, kolla Hur man skriver egna Python-paket.
Python har ett centralt paketförråd som heter PyPI (Python Packages Index). När du installerar ett Python-paket med pip, kommer det att ladda ner paketet från PyPI (om du inte anger ett annat förråd). För att distribuera vårt patologipaket måste vi ladda upp det till PyPI och ge några extra metadata som PyPI kräver. Stegen är:
Du kan skapa ett konto på PyPI-webbplatsen. Skapa sedan en .pypirc filen i din hemkatalog:
[distutils] index-servrar = pypi [pypi] repository = https://pypi.python.org/pypi användarnamn = the_gigi
För teständamål kan du lägga till en "pypitest" indexserver till din .pypirc fil:
[distutils] index-servrar = pypi pypitest [pypitest] repository = https://testpypi.python.org/pypi användarnamn = the_gigi [pypi] repository = https://pypi.python.org/pypi användarnamn = the_gigi
Om det här är första utgåvan av ditt paket måste du registrera det med PyPI. Använd registerkommandot för setup.py. Det kommer att fråga dig för ditt lösenord. Observera att jag pekar på det i testförvaret här:
$ python setup.py register -r pypitest löpregister kör egg_info skriv pathology.egg-info / PKG-INFO skriva dependency_links till pathology.egg-info / dependency_links.txt skriver högsta namn till pathology.egg-info / top_level.txt läs manifestfilen 'pathology.egg-info / SOURCES.txt' skriv manifestfilen 'pathology.egg-info / SOURCES.txt' körkontroll Lösenord: Registrering av patologi till https://testpypi.python.org/pypi Serverrespons (200 ): OK
Nu när paketet är registrerat kan vi ladda upp det. Jag rekommenderar att du använder garn, vilket är säkrare. Installera det som vanligt med pip installera garn
. Ladda sedan upp ditt paket med tvillingar och ge ditt lösenord (redigeras nedan):
$ twine uppladdning -r pypitest -pdist / * Överföringsfördelningar till https://testpypi.python.org/pypi Uppladdningspatologi-0.1-py3-none-any.whl [=================== =============] 5679/5679 - 00:00:02 Uppladdning av patologi-0.1.tar.gz [=================== =============] 4185/4185 - 00:00:01
För en djupare dyka in i ämnet att distribuera dina paket, kolla Hur delar du dina Python-paket.
I denna handledning gick vi igenom den fullständiga processen att skriva ett Python-bibliotek, förpacka det och distribuera det via PyPI. Vid denna tidpunkt borde du ha alla verktyg för att skriva och dela dina bibliotek med världen.
Tveka inte att se vad vi har till salu och studera på marknaden, och fråga eventuella frågor och ge din värdefulla feedback genom att använda flödet nedan.