te maken Python, krachtig en veelzijdig als het is, mist een paar belangrijke mogelijkheden uit de doos. Voor een, Python biedt geen native mechanisme voor het compileren van een Python programma in een standalone uitvoerbaar pakket.

om eerlijk te zijn, de oorspronkelijke use case voor Python heeft nooit een beroep gedaan op standalone pakketten. Python-programma ‘ s zijn over het algemeen in-place uitgevoerd op systemen waar een kopie van de Python-interpreter woonde. Maar de stijgende populariteit van Python heeft geleid tot een grotere vraag naar het uitvoeren van Python apps op systemen zonder geïnstalleerde Python runtime.,

verschillende derden hebben oplossingen ontwikkeld voor het implementeren van standalone Python-apps. De meest populaire oplossing van de bos, en de meest volwassen, is PyInstaller. PyInstaller maakt het proces van het verpakken van een Python app helemaal pijnloos te gaan, maar het gaat een lange weg daar.

In dit artikel zullen we de basisprincipes van het gebruik van PyInstaller verkennen, waaronder hoe PyInstaller werkt, hoe PyInstaller te gebruiken om een zelfstandig Python-uitvoerbaar bestand te maken, hoe de Python-uitvoerbare bestanden die u maakt te fine-tunen, en hoe u enkele van de veelvoorkomende valkuilen kunt vermijden die bij het gebruik van PyInstaller horen.,

een PyInstaller-pakket aanmaken

PyInstaller is een Python-pakket, geïnstalleerd met pip (pip install pyinstaller). PyInstaller kan worden geïnstalleerd in uw standaard Python installatie, maar het is het beste om een virtuele omgeving te creëren voor het project dat u wilt verpakken en installeren PyInstaller er.

PyInstaller werkt door het lezen van uw Python-programma, het analyseren van alle imports die het maakt, en het bundelen van kopieën van die imports met uw programma. PyInstaller leest in uw programma vanaf de ingang., Bijvoorbeeld, als het invoerpunt van uw programma myapp.py is, zou u pyinstaller myapp.py uitvoeren om de analyse uit te voeren. PyInstaller kan veel veelvoorkomende Python-pakketten detecteren en automatisch verpakken, zoals NumPy, maar in sommige gevallen moet u wellicht hints geven. (Hierover later meer.)

na het analyseren van uw code en het ontdekken van alle bibliotheken en modules die het gebruikt, PyInstaller genereert dan een “spec file.”Een Python script met de extensie .spec, dit bestand bevat details over hoe uw Python app moet worden ingepakt., De eerste keer dat u PyInstaller op uw app, PyInstaller zal een spec-bestand te genereren uit het niets en bevolken het met een aantal gezonde standaardinstellingen. Gooi dit bestand niet weg; het is de sleutel tot het verfijnen van een PyInstaller implementatie!

ten slotte probeert PyInstaller een uitvoerbaar bestand te maken vanuit de app, gebundeld met al zijn afhankelijkheden. Als het klaar is, zal een submap genaamd dist (standaard; u bent vrij om een andere naam op te geven) verschijnen in de projectmap., Dit bevat op zijn beurt een map die uw gebundelde app is — het heeft een .exe bestand om uit te voeren, samen met alle bibliotheken en andere aanvullende bestanden die nodig zijn.

het enige wat u hoeft te doen om uw programma te distribueren, is deze map verpakken als een .zip bestand of een andere bundel. De bundel moet meestal worden geëxtraheerd in een map waar de gebruiker schrijfrechten heeft om uit te voeren.

IDG

A .spec-bestand wordt gebruikt om een uitvoerbaar bestand te maken met PyInstaller., Let op de namespaces in excludes. Deze worden weggelaten uit de gemaakte bundel om ruimte te besparen.

een PyInstaller-pakket testen

Er is een goede kans dat uw eerste poging om PyInstaller te gebruiken om een app te verpakken niet volledig succesvol zal zijn.

om te controleren of uw PyInstaller pakket werkt, navigeert u naar de map die het gebundelde uitvoerbare bestand bevat en voert u het .exe bestand daar uit vanaf de opdrachtregel., Als het niet wordt uitgevoerd, moeten de fouten die u ziet afgedrukt op de opdrachtregel een hint geven over wat er mis is.

De meest voorkomende reden dat een PyInstaller-pakket faalt, is dat PyInstaller een vereist bestand niet kon bundelen. Dergelijke ontbrekende bestanden vallen in een paar categorieën:

  • Verborgen of ontbrekende import: soms kan PyInstaller de import van een pakket of bibliotheek niet detecteren, meestal omdat het dynamisch wordt geïmporteerd. Het pakket of de bibliotheek moet handmatig worden opgegeven.,
  • ontbrekende standalone bestanden: als het programma afhankelijk is van externe gegevensbestanden die met het programma gebundeld moeten worden, kan PyInstaller dit niet weten. Je moet de bestanden handmatig opnemen.
  • ontbrekende binaries: hier weer, als uw programma afhankelijk is van een externe binary zoals a .DLL die PyInstaller niet kan detecteren, moet u handmatig opnemen.

het goede nieuws is dat PyInstaller een eenvoudige manier biedt om met bovenstaande problemen om te gaan., Het .spec bestand aangemaakt door PyInstaller bevat velden die we kunnen invullen om de details te geven die PyInstaller miste.

Open het .spec bestand in een teksteditor en zoek naar de definitie van het Analysis object. Verschillende parameters die worden doorgegeven aan Analysis zijn lege lijsten, maar ze kunnen worden bewerkt om de ontbrekende details op te geven:

  • hiddenimports voor verborgen of ontbrekende imports: voeg aan deze lijst een of meer strings toe met de namen van bibliotheken die u in uw app wilt opnemen., Als u bijvoorbeeld pandas en bokeh wilt toevoegen, zou u dat opgeven als . Merk op dat de bibliotheken in kwestie moeten worden geïnstalleerd in dezelfde instantie van Python waar je PyInstaller draait.
  • datas voor ontbrekende standalone bestanden: voeg hier een of meer specificaties toe voor bestanden in uw projectstructuur die u bij uw project wilt opnemen., Elk bestand moet worden doorgegeven als een tupel die het relatieve pad aangeeft naar het bestand in je project directory en het relatieve pad binnen de distributie directory waar je het bestand wilt plaatsen. Bijvoorbeeld, als u een bestand ./models/mainmodel.dat had dat u met uw app wilde opnemen, en u wilt het in een overeenkomende submap in uw distributiemap plaatsen, zou u ('./models/mainmodel.dat','./models') gebruiken als één regel in de hiddenimports lijst. Merk op dat u glob-stijl jokertekens kunt gebruiken om meer dan één bestand op te geven.,
  • binaries voor ontbrekende standalone binaries: net als bij datas, kunt u binaries gebruiken om een lijst met tupels door te geven die de locaties van binaries in de projectboom en hun bestemmingen in de distributiemap specificeren. Nogmaals, u kunt glob-stijl jokertekens gebruiken.

houd er rekening mee dat alle lijsten die aan Analysis worden doorgegeven, eerder programmatisch kunnen worden gegenereerd in het .spec bestand., Immers, het .spec bestand is gewoon een Python script met een andere naam.

nadat u wijzigingen aanbrengt in het .spec bestand, voer PyInstaller opnieuw uit om het pakket opnieuw te maken. Zorg er vanaf nu echter voor dat u het gewijzigde .spec bestand als parameter doorgeeft (bijvoorbeeld pyinstaller myapp.spec). Test het uitvoerbare bestand als voorheen. Als er nog iets kapot is, kun je het .spec bestand opnieuw bewerken en het proces herhalen totdat alles werkt.,

tot slot, als u tevreden bent dat alles werkt zoals bedoeld, wilt u misschien het .spec Bestand Bewerken om te voorkomen dat uw packaged app een commandoregelvenster presenteert wanneer deze wordt gestart. In het EXE Objectinstellingen in het .spec bestand, stel console=Falsein. Het onderdrukken van de console is handig als uw app heeft een GUI en u niet wilt dat een valse command-line venster leidt gebruikers op een dwaalspoor. Natuurlijk, niet veranderen deze instelling als uw app vereist een command line.,

het verfijnen van een PyInstaller-pakket

zodra u uw app hebt verpakt met PyInstaller en goed werkt, is het volgende wat u waarschijnlijk wilt doen het een beetje af te slanken. PyInstaller pakketten staan niet bekend als svelte.

omdat Python een dynamische taal is, is het moeilijk te voorspellen wat er nodig is tijdens runtime door een bepaald programma. Om die reden, wanneer PyInstaller detecteert een pakket import, het omvat alles in dat pakket, of het nu daadwerkelijk wordt gebruikt tijdens runtime door uw programma.

Hier is het goede nieuws., PyInstaller bevat een mechanisme voor het selectief uitsluiten van volledige pakketten, of individuele namespaces binnen pakketten. Bijvoorbeeld, laten we zeggen dat uw programma importeert pakket foo, die foo.bar en foo.bipbevat. Als u zeker weet dat uw programma alleen logica gebruikt in foo.bar, kunt u veilig foo.bip uitsluiten en wat ruimte besparen.

hiervoor gebruikt u de parameter excludes doorgegeven aan het Analysis object in het .spec bestand., U kunt een lijst met namen doorgeven-top-level modules of gestippelde naamruimten – om uit te sluiten van uw pakket. Bijvoorbeeld, om foo.bip uit te sluiten, zou u gewoon opgeven.

IDG

de leverbare map gemaakt door PyInstaller. Vanwege het grote aantal bestanden in de map, kan een derde partij installer project zoals NSIS worden gebruikt om de map in te pakken in een zelf-uitpakkend archief, en automatisch een snelkoppeling naar het uitvoerbare bestand te maken.,

een veel voorkomende uitsluiting die u kunt maken is tkinter, de Python-bibliotheek voor het maken van eenvoudige platformonafhankelijke grafische gebruikersinterfaces. Standaard zijn tkinter en al zijn ondersteunende bestanden verpakt met een PyInstaller project. Als u tkinter niet gebruikt in uw project, kunt u het uitsluiten door'tkinter' toe te voegen aan deexcludes lijst. Het weglaten van tkinter zal de grootte van het pakket met ongeveer 7 MB verminderen.

een andere veel voorkomende uitsluiting zijn testsuites., Als een pakket dat uw programma invoer heeft een test suite, de test suite kan uiteindelijk worden opgenomen in uw PyInstaller pakket. Tenzij u de testsuite daadwerkelijk uitvoert in uw geïmplementeerd programma, kunt u deze veilig uitsluiten.

houd er rekening mee dat pakketten die met uitsluitingen zijn gemaakt, grondig moeten worden getest voordat ze worden gebruikt. Als je uiteindelijk met uitzondering van functionaliteit die wordt gebruikt in een toekomstig scenario dat u niet had verwacht, uw app zal breken.

PyInstaller tips

  • Bouw uw PyInstaller-pakket op het besturingssysteem waarop u wilt implementeren., PyInstaller ondersteunt geen cross-platform builds. Als u uw standalone Python-app op MacOS -, Linux-en Windows-systemen wilt implementeren, moet u PyInstaller installeren en afzonderlijke versies van de app op elk van deze besturingssystemen bouwen.
  • Bouw uw PyInstaller-pakket terwijl u uw app ontwikkelt. Zodra u weet dat u uw project met PyInstaller gaat implementeren, bouwt u uw .spec bestand en begint u met het verfijnen van het PyInstaller-pakket parallel met de ontwikkeling van uw app., Op deze manier kunt u uitsluitingen of insluitingen toe te voegen als je gaat, en test de manier waarop nieuwe functies worden ingezet met de app als je ze schrijft.
  • gebruik PyInstaller ‘ s --onefile modus niet. PyInstaller bevat een commandoregelschakelaar, --onefile, die uw hele app in een enkel zelfuitpakkend uitvoerbaar bestand verpakt. Dit klinkt als een geweldig idee — je hoeft maar één bestand te leveren! – maar het heeft een aantal valkuilen. Wanneer u de app uitvoert, moet het eerst alle bestanden in het uitvoerbare bestand uitpakken naar een tijdelijke map., Als de app groot is (200MB, bijvoorbeeld), kan uitpakken een vertraging van enkele seconden betekenen. Gebruik in plaats daarvan de standaard single-directory modus, en pak alles in als een .zip bestand.
  • Maak een installatieprogramma aan voor uw PyInstaller-app. Als u een andere manier wilt om uw app te implementeren dan een .zip-bestand, overweeg het gebruik van een installatieprogramma hulpprogramma zoals de open source Nullsoft Scriptable installatiesysteem. Het voegt zeer weinig overhead aan de grootte van de deliverable en kunt u vele aspecten van het installatieproces configureren, zoals het maken van snelkoppelingen naar uw uitvoerbare.,
  • verwacht geen speedups. PyInstaller is een verpakkingssysteem, geen compiler of optimizer. Code verpakt met PyInstaller niet sneller dan het zou draaien op het originele systeem. Als je Python code wilt versnellen, gebruik dan een C-versnelde bibliotheek die geschikt is voor de taak, of een project zoals Cython.,w om de snelheid van Python
  • het installeren van Python op een slimme manier
  • Betere Python project management met Poëzie
  • Virtualenv en venv: Python virtuele omgevingen uitgelegd
  • Python-virtualenv en venv do ’s en don’ ts
  • Python-threading en subprocessen uitgelegd
  • het gebruik van de Python debugger
  • Hoe te gebruiken timeit profiel Python code
  • Hoe te gebruiken cProfile profiel Python code
  • aan de slag met async in Python
  • Hoe te gebruiken asyncio in Python
  • Hoe om te zetten Python om JavaScript (en weer terug)