Cara menggunakan PyInstaller untuk membuat Python yang boleh dilaksanakan

Python, kuat dan serba boleh seperti itu, tidak mempunyai beberapa keupayaan utama di luar kotak. Untuk satu, Python tidak menyediakan mekanisme asli untuk menyusun program Python ke dalam pakej yang boleh dilaksanakan secara mandiri.

Agar adil, kes penggunaan asal untuk Python tidak pernah memerlukan pakej yang berdiri sendiri. Program Python, pada umumnya, telah dijalankan di sistem di mana salinan jurubahasa Python tinggal. Tetapi populariti Python yang semakin meningkat telah mewujudkan permintaan yang lebih besar untuk menjalankan aplikasi Python pada sistem tanpa waktu operasi Python yang dipasang.

Beberapa pihak ketiga telah mencipta penyelesaian untuk menggunakan aplikasi Python yang berdiri sendiri. Penyelesaian kumpulan yang paling popular, dan yang paling matang, adalah PyInstaller. PyInstaller tidak menjadikan proses pembungkusan aplikasi Python menjadi sangat menyakitkan, tetapi prosesnya sangat lama.

Dalam artikel ini, kami akan meneroka asas penggunaan PyInstaller termasuk bagaimana PyInstaller berfungsi, bagaimana menggunakan PyInstaller untuk membuat Python yang dapat dijalankan secara mandiri, bagaimana menyempurnakan pelaksanaan Python yang anda buat, dan bagaimana mengelakkan beberapa perangkap biasa yang berlaku dengan menggunakan PyInstaller.

Membuat pakej PyInstaller

PyInstaller adalah pakej Python, dipasang dengan pip( pip install pyinstaller). PyInstaller boleh dipasang dalam pemasangan Python lalai anda, tetapi yang terbaik adalah membuat persekitaran maya untuk projek yang ingin anda bungkus dan pasangkan PyInstaller di sana.

PyInstaller berfungsi dengan membaca program Python anda, menganalisis semua import yang dibuatnya, dan menggabungkan salinan import tersebut dengan program anda. PyInstaller membaca dalam program anda dari titik masuknya. Contohnya, jika titik masuk program myapp.pyanda, anda akan menjalankan pyinstaller myapp.pyanalisis. PyInstaller dapat mengesan dan secara automatik mengemas banyak pakej Python biasa, seperti NumPy, tetapi anda mungkin perlu memberikan petunjuk dalam beberapa kes. (Lebih lanjut mengenai ini kemudian.)

Setelah menganalisis kod anda dan menemui semua perpustakaan dan modul yang digunakannya, PyInstaller kemudian menghasilkan "fail spesifikasi." Skrip Python dengan ekstensi .spec, fail ini merangkumi perincian tentang bagaimana aplikasi Python anda perlu dikemas. Kali pertama anda menjalankan PyInstaller pada aplikasi anda, PyInstaller akan menghasilkan fail spesifikasi dari awal dan mengisi dengan beberapa default yang waras. Jangan buang fail ini; ini adalah kunci untuk memperbaiki penyebaran PyInstaller!

Akhirnya, PyInstaller cuba menghasilkan aplikasi yang boleh dilaksanakan dari aplikasi, digabungkan dengan semua kebergantungannya. Setelah selesai, subfolder bernama dist (secara lalai; anda bebas untuk menentukan nama yang berbeza) akan muncul di direktori projek. Ini seterusnya mengandungi direktori yang merupakan aplikasi gabungan anda - ia mempunyai .exefail untuk dijalankan, bersama dengan semua perpustakaan dan fail tambahan lain yang diperlukan.

Apa yang perlu anda lakukan untuk menyebarkan program anda, kemudian, .zipbungkus direktori ini sebagai fail atau kumpulan lain. Bundel biasanya perlu diekstrak dalam direktori di mana pengguna mempunyai kebenaran menulis untuk dijalankan.

Menguji pakej PyInstaller

Kemungkinan percubaan pertama anda menggunakan PyInstaller untuk mengemas aplikasi tidak akan berjaya sepenuhnya.

Untuk memeriksa sama ada pakej PyInstaller anda berfungsi, arahkan ke direktori yang berisi paket yang dapat dieksekusi dan jalankan .exefail di sana dari baris perintah. Sekiranya gagal dijalankan, kesalahan yang anda lihat dicetak ke baris arahan harus memberikan petunjuk mengenai apa yang salah.

Sebab paling umum pakej PyInstaller gagal ialah PyInstaller gagal mengikat fail yang diperlukan. Fail yang hilang itu termasuk dalam beberapa kategori:

  • Import tersembunyi atau hilang : Kadang-kadang PyInstaller tidak dapat mengesan import pakej atau perpustakaan, biasanya kerana ia diimport secara dinamik. Pakej atau pustaka perlu ditentukan secara manual.
  • Fail mandiri tidak ada : Sekiranya program bergantung pada fail data luaran yang perlu digabungkan dengan program, PyInstaller tidak tahu. Anda perlu memasukkan fail secara manual.
  • Hilang binari : Di sini sekali lagi, jika program anda bergantung kepada binari luaran seperti .DLL yang PyInstaller tidak dapat mengesan, anda perlu memasukkan secara manual.

Berita baiknya ialah PyInstaller menyediakan cara mudah untuk mengatasi masalah di atas. The .specfile dicipta oleh PyInstaller termasuk bidang yang kita boleh mengisi memberikan butir-butir yang PyInstaller terlepas.

Buka .specfail dalam penyunting teks dan cari definisi Analysisobjek. Beberapa parameter yang dilewatkan Analysisadalah senarai kosong, tetapi boleh diedit untuk menentukan butiran yang hilang:

  • hiddenimportsuntuk import tersembunyi atau hilang : Tambahkan ke senarai ini satu atau lebih rentetan dengan nama perpustakaan yang anda mahu sertakan dengan aplikasi anda. Sekiranya anda ingin menambahkan pandasdan bokeh, misalnya, anda akan menetapkannya sebagai  ['pandas','bokeh']. Perhatikan bahawa perpustakaan yang dimaksudkan mesti dipasang dalam contoh Python yang sama di mana anda menjalankan PyInstaller.
  • datasuntuk fail mandiri yang hilang : Tambahkan di sini satu atau lebih spesifikasi untuk fail di pokok projek anda yang ingin anda sertakan dengan projek anda. Setiap fail harus dilewatkan sebagai tuple yang menunjukkan jalan relatif ke file di direktori proyek anda dan jalur relatif di dalam direktori pengedaran tempat anda ingin meletakkan file tersebut. Sebagai contoh, jika anda mempunyai fail ./models/mainmodel.datyang ingin anda sertakan dengan aplikasi anda, dan anda ingin meletakkannya di subdirektori yang sesuai di direktori pengedaran anda, anda akan menggunakan ('./models/mainmodel.dat','./models')sebagai satu entri dalam hiddenimportssenarai. Perhatikan bahawa anda boleh menggunakan globwildcard gaya untuk menentukan lebih daripada satu fail.
  • binariesuntuk binari mandiri yang hilang : Seperti halnyadatas , anda dapat menggunakan binariesuntuk menyampaikan senarai tupel yang menentukan lokasi binari di pohon projek dan tujuannya di direktori pengedaran. Sekali lagi, anda boleh menggunakan globwildcard gaya.

Perlu diingat bahawa mana-mana senarai yang diserahkan Analysisdapat dibuat secara teratur di awal .specfail. Lagipun, .specfail itu hanyalah skrip Python dengan nama lain.

Setelah anda membuat perubahan pada .specfail, jalankan semula PyInstaller untuk membina semula pakej. Namun, mulai sekarang, pastikan untuk meneruskan .specfail yang diubah sebagai parameter (mis pyinstaller myapp.spec.). Uji yang boleh dilaksanakan seperti sebelumnya. Sekiranya sesuatu masih rosak, anda boleh menyunting semula .specfail dan mengulangi prosesnya sehingga semuanya berfungsi.

Akhirnya, apabila anda berpuas hati semuanya berjalan seperti yang diharapkan, anda mungkin ingin mengedit  .specfail untuk mengelakkan aplikasi anda yang dibungkus daripada menampilkan tetingkap baris perintah ketika dilancarkan. Dalam EXEtetapan objek dalam .specfail, tetapkan  console=False. Menindas konsol berguna jika aplikasi anda mempunyai GUI dan anda tidak mahu tetingkap baris perintah palsu menyesatkan pengguna. Sudah tentu, jangan ubah tetapan ini jika aplikasi anda memerlukan baris perintah.

Memperhalusi pakej PyInstaller

Setelah aplikasi anda dibungkus dengan PyInstaller dan berjalan dengan betul, perkara seterusnya yang mungkin anda mahu lakukan adalah mengurangkannya sedikit. Pakej PyInstaller tidak dikenali sebagai yang hebat

Oleh kerana Python adalah bahasa yang dinamik, sukar untuk meramalkan apa yang akan diperlukan pada waktu berjalan oleh program tertentu. Atas sebab itu, apabila PyInstaller mengesan import pakej, ia merangkumi semua yang ada dalam pakej itu, sama ada sebenarnya digunakan atau tidak semasa program dijalankan oleh program anda. 

Inilah berita baiknya. PyInstaller merangkumi mekanisme untuk secara selektif mengecualikan keseluruhan pakej, atau ruang nama individu dalam pakej. Sebagai contoh, katakan program anda mengimport pakej foo, yang merangkumi foo.bardan foo.bip. Sekiranya anda mengetahui bahawa program anda hanya menggunakan logik foo.bar, anda boleh mengecualikan foo.bip dan menjimatkan ruang dengan selamat.

Untuk melakukan ini, anda menggunakan excludesparameter yang diteruskan ke Analysisobjek dalam .specfail. Anda boleh memasukkan senarai nama - modul peringkat teratas, atau ruang nama bertitik - untuk dikecualikan dari pakej anda. Sebagai contoh, untuk mengecualikan foo.bip, anda hanya akan menentukan  ['foo.bip'].

Satu pengecualian umum yang boleh anda buat ialah tkinter, perpustakaan Python untuk membuat antara muka pengguna grafik silang platform sederhana. Secara lalai,  tkinterdan semua fail sokongannya dibungkus dengan projek PyInstaller. Sekiranya anda tidak menggunakan tkinterprojek anda, anda boleh mengecualikannya dengan menambahkan 'tkinter'ke excludessenarai. Mengabaikan tkinterakan mengurangkan saiz pakej sekitar 7 MB.

Pengecualian umum yang lain adalah ujian suites. Sekiranya pakej yang diimport oleh program anda mempunyai suite ujian, rangkaian ujian akhirnya dapat dimasukkan ke dalam pakej PyInstaller anda. Kecuali anda benar-benar menjalankan rangkaian ujian dalam program yang anda gunakan, anda boleh mengecualikannya dengan selamat.

Ingatlah bahawa paket yang dibuat menggunakan pengecualian harus diuji secara menyeluruh sebelum digunakan. Sekiranya anda tidak termasuk fungsi yang digunakan dalam beberapa senario masa depan yang tidak anda jangkakan, aplikasi anda akan rosak.

Petua PyInstaller

  • Bina pakej PyInstaller anda pada OS yang anda rancangkan.  PyInstaller tidak menyokong binaan lintas platform. Sekiranya anda perlu menggunakan aplikasi Python yang berdiri sendiri pada sistem MacOS, Linux, dan Windows, maka anda perlu memasang PyInstaller dan membina versi aplikasi yang berasingan pada setiap sistem operasi ini. 
  • Bina pakej PyInstaller anda semasa anda mengembangkan aplikasi anda.  Sebaik sahaja anda tahu bahawa anda akan menggunakan projek anda dengan PyInstaller, bina .specfail anda dan mulakan penyempurnaan pakej PyInstaller selari dengan pengembangan aplikasi anda. Dengan cara ini anda boleh menambahkan pengecualian atau penyertaan semasa anda pergi, dan menguji cara penggunaan ciri baru dengan aplikasi semasa anda menulisnya.
  • Jangan gunakan --onefilemod PyInstaller  .  PyInstaller termasuk suis baris perintah --onefile, yang mengemas seluruh aplikasi anda ke dalam satu eksekusi sendiri yang dapat dilaksanakan. Ini terdengar seperti idea hebat - anda hanya perlu menghantar satu fail! - tetapi ia mempunyai beberapa perangkap. Setiap kali anda menjalankan aplikasinya, aplikasi mesti membongkar semua fail yang dapat dieksekusi ke direktori sementara terlebih dahulu. Sekiranya aplikasinya besar (misalnya, 200MB), pembongkaran dapat berarti kelewatan beberapa saat. Gunakan mod direktori tunggal lalai, dan hanya kemas semuanya sebagai .zipfail.
  • Buat pemasang untuk aplikasi PyInstaller anda.  Sekiranya anda menginginkan cara untuk menggunakan aplikasi anda selain daripada fail .zip, pertimbangkan untuk menggunakan utiliti pemasang seperti Sistem Pemasangan Skrip Nullsoft sumber terbuka. Ini menambah sedikit overhead pada ukuran yang dapat dikirimkan dan memungkinkan Anda mengkonfigurasi banyak aspek proses pemasangan, seperti membuat jalan pintas untuk yang dapat Anda laksanakan.
  • Jangan mengharapkan peningkatan.  PyInstaller adalah  sistem pembungkusan , bukan  penyusun  atau  pengoptimum . Kod yang dibungkus dengan PyInstaller tidak berjalan lebih cepat daripada yang dijalankan semasa dijalankan pada sistem asal. Sekiranya anda ingin mempercepat kod Python, gunakan perpustakaan dipercepat C yang sesuai dengan tugas, atau projek seperti Cython.

Bagaimana untuk melakukan lebih banyak perkara dengan Python

  • Tutorial Cython: Cara mempercepat Python
  • Cara memasang Python dengan cara yang bijak
  • Pengurusan projek Python yang lebih baik dengan Puisi
  • Virtualenv dan venv: Persekitaran maya Python dijelaskan
  • Python virtualenv dan venv lakukan dan tidak boleh dilakukan
  • Penjelasan dan proses subtitle Python dijelaskan
  • Cara menggunakan debugger Python
  • Cara menggunakan timeit untuk profil kod Python
  • Cara menggunakan cProfile untuk profil kod Python
  • Mulakan dengan async di Python
  • Cara menggunakan asyncio di Python
  • Cara menukar Python ke JavaScript (dan kembali lagi)