Kako koristiti PyInstaller za stvaranje Python izvršnih datoteka

Pythonu, moćan i svestran kakav jest, nedostaje nekoliko ključnih mogućnosti. Kao prvo, Python ne pruža izvorni mehanizam za kompajliranje programa Python u samostalni izvršni paket.

Da budemo pošteni, izvorni slučaj upotrebe Pythona nikada nije tražio samostalne pakete. Python programi uglavnom su se pokrenuli u sustavima u kojima je živjela kopija tumača Python. Ali sve veća popularnost Pythona stvorila je veću potražnju za pokretanjem Python aplikacija na sustavima bez instaliranog Python runtimea.

Nekoliko trećih strana osmislilo je rješenja za uvođenje samostalnih Python aplikacija. Najpopularnije rješenje i najzrelije rješenje je PyInstaller. PyInstaller ne čini postupak pakiranja aplikacije Python potpuno bezbolnim, ali tamo ide daleko.

U ovom ćemo članku istražiti osnove upotrebe PyInstallera, uključujući kako PyInstaller radi, kako koristiti PyInstaller za stvaranje samostalne izvršne verzije Pythona, kako fino podesiti Python izvršne datoteke koje kreirate i kako izbjeći neke uobičajene zamke koje idu uz upotrebu PyInstallera.

Izrada paketa PyInstaller

PyInstaller je Python paket, instaliran s pip( pip install pyinstaller). PyInstaller se može instalirati u vašu zadanu instalaciju Pythona, ali najbolje je stvoriti virtualno okruženje za projekt koji želite spakirati i tamo instalirati PyInstaller.

PyInstaller radi čitajući vaš program Python, analizirajući sve uvoze koje vrši i spajajući kopije tog uvoza s vašim programom. PyInstaller čita vaš program s njegove ulazne točke. Na primjer, ako je ulazna točka vašeg programa myapp.py, trčali pyinstaller myapp.pybiste izvršiti analizu. PyInstaller može otkriti i automatski spakirati mnoge uobičajene Python pakete, poput NumPy, ali u nekim ćete slučajevima možda trebati dati savjete. (Više o tome kasnije.)

Nakon analize vašeg koda i otkrivanja svih knjižnica i modula koje koristi, PyInstaller tada generira "spec datoteku". Python skripta s nastavkom .spec, ova datoteka sadrži detalje o tome kako treba spakirati vašu aplikaciju Python. Kad prvi put pokrenete PyInstaller u svojoj aplikaciji, PyInstaller će generirati datoteku sa specifikacijama od početka i popuniti je nekim uobičajenim zadanim postavkama. Ne odbacujte ovu datoteku; to je ključ za pročišćavanje implementacije PyInstallera!

Napokon, PyInstaller pokušava iz aplikacije izvršiti izvršnu datoteku u paketu sa svim ovisnostima. Kad završi, dist u direktoriju projekta pojavit će se podmapa s imenom (prema zadanim postavkama; možete slobodno navesti drugo ime). Ovo pak sadrži direktorij koji je vaša paketna aplikacija - ima .exedatoteku koju treba pokrenuti, zajedno sa svim potrebnim knjižnicama i ostalim dodatnim datotekama.

Sve što trebate učiniti da biste distribuirali svoj program, jest spakiranje ovog direktorija u .zipdatoteku ili neki drugi paket. Paket će obično trebati izvući u direktorij u kojem korisnik ima dozvole za pisanje kako bi se mogao pokrenuti.

Testiranje paketa PyInstaller

Postoji velika šansa da vaš prvi pokušaj upotrebe PyInstallera za pakiranje aplikacije neće biti potpuno uspješan.

Da biste provjerili radi li vaš paket PyInstaller, idite do direktorija koji sadrži paket u izvedbi i .exetamo iz naredbenog retka pokrenite datoteku. Ako se ne uspije pokrenuti, pogreške koje ćete vidjeti ispisane u naredbenom retku trebale bi dati savjet o tome što nije u redu.

Najčešći razlog neuspjeha paketa PyInstaller je taj što PyInstaller nije uspio povezati potrebnu datoteku. Takve datoteke koje nedostaju spadaju u nekoliko kategorija:

  • Skriveni ili nedostajući uvoz : Ponekad PyInstaller ne može otkriti uvoz paketa ili knjižnice, obično zato što se dinamički uvozi. Paket ili knjižnicu trebat će ručno navesti.
  • Nedostaju samostalne datoteke : Ako program ovisi o vanjskim podatkovnim datotekama koje je potrebno povezati s programom, PyInstaller to nikako ne može znati. Morat ćete ručno uključiti datoteke.
  • Nedostaju binarne datoteke : I ovdje, ako vaš program ovisi o vanjskoj binarnoj datoteci poput .DLL-a koju PyInstaller ne može otkriti, morat ćete ga ručno uključiti.

Dobra vijest je da PyInstaller pruža jednostavan način za rješavanje gore navedenih problema. .specDatoteka stvorio PyInstaller sadrži polja možemo popuniti u pružiti podatke koji PyInstaller propustili.

Otvorite .specdatoteku u uređivaču teksta i potražite definiciju Analysisobjekta. Nekoliko parametara prosljeđenih Analysisprazni su popisi, ali ih je moguće urediti kako bi se odredili detalji koji nedostaju:

  • hiddenimportsza skriveni ili nedostajući uvoz : dodajte na ovaj popis jedan ili više nizova s ​​imenima knjižnica koje želite uključiti u svoju aplikaciju. Ako želite dodati pandasi bokeh, na primjer, to biste naveli kao  ['pandas','bokeh']. Imajte na umu da se predmetne knjižnice moraju instalirati u istoj instanci Pythona u kojoj se izvodi PyInstaller.
  • datasza nedostajuće samostalne datoteke : ovdje dodajte jednu ili više specifikacija za datoteke u vašem stablu projekata koje želite uključiti u svoj projekt. Svaka datoteka mora se proslijediti kao skup koji označava relativni put do datoteke u direktoriju vašeg projekta i relativni put unutar distribucijskog direktorija gdje želite smjestiti datoteku. Na primjer, ako ste imali datoteku ./models/mainmodel.datkoju ste željeli uključiti u svoju aplikaciju i želite je smjestiti u poddirektorij koji se podudara u vašem direktoriju distribucije, koristili biste ('./models/mainmodel.dat','./models')jedan unos na hiddenimportspopisu. Imajte na umu da za korištenje globviše datoteka možete koristiti zamjenske znakove -style.
  • binariesza nedostajuće samostalne binarne datoteke : Kao i kod datas, možete koristiti binariesza prosljeđivanje popisa korpica koji određuju mjesta binarnih datoteka u stablu projekata i njihova odredišta u direktoriju distribucije. Opet, možete koristiti globzamjenske znakove u stilu.

Imajte na umu da se bilo koji od popisa proslijeđenih Analysismože programski generirati ranije u .specdatoteci. Napokon, .specdatoteka je samo Python skripta pod drugim imenom.

Nakon što napravite promjene u .specdatoteci, ponovo pokrenite PyInstaller za ponovnu izgradnju paketa. Međutim, od sada pazite da modificiranu .specdatoteku prosljeđujete kao parametar (npr pyinstaller myapp.spec.). Testirajte izvršnu datoteku kao i prije. Ako je nešto i dalje pokvareno, možete ponovo urediti .specdatoteku i ponoviti postupak dok sve ne uspije.

Konačno, kada budete zadovoljni da sve radi kako je predviđeno, možda ćete htjeti urediti  .specdatoteku kako biste spriječili da vaša zapakirana aplikacija prikazuje prozor naredbenog retka prilikom pokretanja. U EXEpostavkama objekta u .specdatoteci postavite  console=False. Suzbijanje konzole korisno je ako vaša aplikacija ima GUI i ako ne želite lažni prozor naredbenog retka koji zaluta korisnike. Naravno, nemojte mijenjati ovu postavku ako vaša aplikacija zahtijeva naredbeni redak.

Pročišćavanje paketa PyInstaller

Jednom kad svoju aplikaciju zapakirate s PyInstallerom i pravilno se pokrene, sljedeće što ćete vjerojatno željeti je malo je smanjiti. Paketi PyInstaller nisu poznati po tome što su tanki.

Budući da je Python dinamičan jezik, teško je predvidjeti što će biti potrebno tijekom izvođenja određenog programa. Iz tog razloga, kada PyInstaller otkrije uvoz paketa, uključuje sve u tom paketu, bez obzira koristi li ga vaš program u vrijeme izvođenja. 

Evo dobrih vijesti. PyInstaller uključuje mehanizam za selektivno izuzeće cijelih paketa ili pojedinačnih prostora imena unutar paketa. Na primjer, recimo da vaš program uvozi paket foo, koji uključuje foo.bari foo.bip. Ako foo.barpouzdano znate da vaš program koristi samo logiku , možete sigurno isključiti foo.bip i uštedjeti malo prostora.

Da biste to učinili, koristite excludesparametar proslijeđen Analysisobjektu u .specdatoteci. Možete proslijediti popis imena - moduli najviše razine ili točkasti prostori imena - da biste ih izuzeli iz paketa. Na primjer, da biste izuzeli foo.bip, jednostavno biste naveli  ['foo.bip'].

Jedno uobičajeno izuzeće je tkinterPython biblioteka za stvaranje jednostavnih grafičkih korisničkih sučelja s više platformi. Prema zadanim postavkama,  tkinteri sve njegove datoteke podrške spakirane su s projektom PyInstaller. Ako tkintersvoj projekt ne upotrebljavate , možete ga izuzeti dodavanjem 'tkinter'na excludespopis. Izostanak tkinterće smanjiti veličinu paketa za oko 7 MB.

Još jedno uobičajeno izuzeće su ispitni apartmani. Ako paket koji vaš program uvozi sadrži testni paket, testni paket mogao bi na kraju biti uključen u vaš paket PyInstaller. Ako zapravo ne pokrenete testni paket u svom implementiranom programu, možete ga sigurno izuzeti.

Imajte na umu da pakete stvorene pomoću izuzetaka treba temeljito testirati prije upotrebe. Ako na kraju izuzmete funkcionalnost koja se koristi u nekom budućem scenariju koji niste predvidjeli, aplikacija će se pokvariti.

Savjeti za PyInstaller

  • Izgradite svoj paket PyInstaller na OS-u na kojem planirate implementirati.  PyInstaller ne podržava izradu više platformi. Ako trebate instalirati samostalnu aplikaciju Python na MacOS, Linux i Windows sustave, tada ćete morati instalirati PyInstaller i izgraditi zasebne verzije aplikacije na svakom od ovih operativnih sustava. 
  • Izradite svoj paket PyInstaller dok razvijate svoju aplikaciju.  Čim saznate da ćete svoj projekt implementirati s PyInstallerom, izradite svoju .specdatoteku i paralelno s razvojem svoje aplikacije započnite s pročišćavanjem paketa PyInstaller. Na taj način možete dodavati izuzimanja ili uključivanja tijekom testiranja i testirati način na koji se nove značajke postavljaju u aplikaciju dok ih pišete.
  • Ne koristite način PyInstaller  --onefile.  PyInstaller uključuje prekidač naredbenog retka --onefile, koji spakira cijelu vašu aplikaciju u jedan samoraspakirajući izvršni program. Ovo zvuči kao izvrsna ideja - morate dostaviti samo jednu datoteku! - ali ima nekih zamki. Kad god pokrenete aplikaciju, prvo mora otpakirati sve datoteke unutar izvršne datoteke u privremeni direktorij. Ako je aplikacija velika (na primjer, 200 MB), raspakiravanje može značiti odgodu od nekoliko sekundi. Umjesto toga upotrijebite zadani način jednog direktorija i samo spakirajte sve u .zipdatoteku.
  • Izradite instalacijski program za svoju aplikaciju PyInstaller.  Ako želite na neki drugi način implementirati svoju aplikaciju osim .zip datoteke, razmislite o upotrebi uslužnog programa za instalaciju poput otvorenog koda Nullsoft Scriptable Install System. Veličini isporučenog proizvoda dodaje vrlo malo dodatnih troškova i omogućuje vam konfiguriranje mnogih aspekata instalacijskog postupka, poput stvaranja prečaca do vaše izvršne datoteke.
  • Ne očekujte ubrzavanja.  PyInstaller je sustav  pakiranja , a ne  kompajler  ili  optimizator . Kôd pakiran s PyInstallerom ne radi ni brže nego što bi se pokrenuo na izvornom sustavu. Ako želite ubrzati Python kôd, upotrijebite C-ubrzanu biblioteku koja odgovara zadatku ili projekt poput Cythona.

Kako učiniti više s Pythonom

  • Vodič za Cython: Kako ubrzati Python
  • Kako instalirati Python na pametan način
  • Bolje upravljanje Python projektima s poezijom
  • Virtualenv i venv: Objašnjena Python virtualna okruženja
  • Python virtualenv i venv čine i ne čine
  • Objašnjeni Python navoji i potprocesi
  • Kako se koristi Python program za ispravljanje pogrešaka
  • Kako koristiti timeit za profiliranje Python koda
  • Kako koristiti cProfile za profiliranje Python koda
  • Započnite s async u Pythonu
  • Kako koristiti asyncio u Pythonu
  • Kako pretvoriti Python u JavaScript (i natrag)