۳۰ شهریور ۱۴۰۳

Techboy

اخبار و اطلاعات روز تکنولوژی

نحوه استفاده از PyInstaller برای ایجاد فایل های اجرایی پایتون

از PyInstaller برای بسته بندی برنامه های پایتون خود در فایل های اجرایی مستقل برای توزیع آسان استفاده کنید.

از PyInstaller برای بسته بندی برنامه های پایتون خود در فایل های اجرایی مستقل برای توزیع آسان استفاده کنید.

قوی و همه کاره است، Python فاقد چند قابلیت کلیدی است. برای مثال، هیچ مکانیزم بومی برای کامپایل یک برنامه پایتون در یک بسته اجرایی مستقل وجود ندارد.

برای منصفانه بودن، مورد استفاده اصلی پایتون هرگز به توزیع مجدد مستقل نیاز نداشت. برنامه‌های پایتون به طور کلی در سیستم‌هایی اجرا می‌شوند که نسخه‌ای از مفسر پایتون در آن زندگی می‌کرد. اما با افزایش محبوبیت این زبان، تقاضای فزاینده ای برای اجرای برنامه های پایتون در سیستم هایی که زمان اجرا پایتون نصب نشده بود نیز افزایش یافت.

چند شخص ثالث راه حل هایی برای استقرار برنامه های کاربردی پایتون مستقل مهندسی کرده اند. محبوب ترین و بالغ ترین راه حل، PyInstaller است. PyInstaller فرآیند بسته‌بندی برنامه پایتون را کاملاً بدون دردسر نمی‌کند، اما راه طولانی را طی می‌کند.

در این مقاله، ما اصول اولیه استفاده از PyInstaller را بررسی خواهیم کرد، از جمله نحوه عملکرد PyInstaller، نحوه استفاده از PyInstaller برای ایجاد یک فایل اجرایی مستقل پایتون، نحوه تنظیم دقیق فایل‌های اجرایی Python که ایجاد می‌کنید، و نحوه اجتناب از برخی از موارد مشکلات رایجی که با استفاده از آن همراه است.

ایجاد بسته PyInstaller

PyInstaller یک بسته پایتون است که با pip (pip install pyinstaller) نصب شده است. می‌توانید PyInstaller را در نصب پیش‌فرض Python خود نصب کنید، اما بهتر است یک محیط مجازی برای پروژه‌ای که می‌خواهید بسته‌بندی کنید ایجاد کنید و PyInstaller را در آنجا نصب کنید.

PyInstaller با خواندن برنامه پایتون شما، تجزیه و تحلیل تمام واردات آن، و بسته‌بندی کپی‌هایی از آن واردات با برنامه شما و یک کپی از زمان اجرا پایتون کار می‌کند.

PyInstaller در برنامه شما از نقطه ورودی خود می خواند. به عنوان مثال، اگر نقطه ورود برنامه شما myapp.py باشد، برای انجام تجزیه و تحلیل، pyinstaller myapp.py را اجرا کنید. PyInstaller می تواند بسیاری از بسته های رایج پایتون مانند NumPy را شناسایی کرده و به طور خودکار بسته بندی کند، اما ممکن است در برخی موارد نیاز به ارائه نکاتی داشته باشید. (در ادامه بیشتر در این مورد.)

پس از تجزیه و تحلیل کد شما و کشف تمام کتابخانه‌ها و ماژول‌هایی که استفاده می‌کند، PyInstaller یک “فایل مشخصات” تولید می‌کند. یک اسکریپت پایتون با پسوند .spec، این فایل شامل جزئیاتی در مورد نحوه بسته بندی برنامه پایتون شما می باشد. اولین باری که PyInstaller را روی برنامه خود اجرا می کنید، یک فایل مشخصات از ابتدا ایجاد می کند و فایل را با پیش فرض های منطقی پر می کند. این فایل را دور نریزید؛ این کلید اصلاح استقرار PyInstaller است!

در نهایت، PyInstaller تلاش می کند تا یک فایل اجرایی از برنامه، همراه با تمام وابستگی های آن تولید کند. پس از پایان کار، زیرپوشه‌ای به نام dist  (به طور پیش‌فرض؛ شما آزادید نام دیگری را مشخص کنید) در فهرست پروژه ظاهر می‌شود. این به نوبه خود حاوی دایرکتوری است که برنامه همراه شما است – یک فایل اجرایی برای اجرا به همراه تمام کتابخانه ها و سایر فایل های تکمیلی مورد نیاز.

تنها کاری که برای توزیع برنامه خود باید انجام دهید این است که این دایرکتوری را به صورت یک فایل .zip یا با بسته دیگری بسته بندی کنید. بسته نرم افزاری معمولاً باید در دایرکتوری استخراج شود که در آن کاربر مجوز نوشتن دارد تا اجرا شود.

یک فایل PyInstaller .spec.

یک فایل .spec برای ایجاد یک فایل اجرایی با PyInstaller استفاده می شود. به فضاهای نام فهرست شده در excludes توجه کنید. اینها برای صرفه جویی در فضا از بسته ایجاد شده خارج می شوند.

ارتقای زبان C# 11 مایکروسافت به خط پایان نزدیک شده است

آزمایش بسته PyInstaller

احتمال زیادی وجود دارد که اولین تلاش شما برای استفاده از PyInstaller برای بسته بندی یک برنامه کاملاً موفق نباشد.

برای بررسی اینکه آیا بسته PyInstaller شما کار می‌کند، به دایرکتوری حاوی فایل اجرایی همراه بروید و فایل اجرایی را از خط فرمان اجرا کنید، نه با دوبار کلیک کردن روی آن در کاوشگر فایل تصویری. اگر اجرا نشد، خطاهایی که در خط فرمان چاپ می‌شوند باید راهنمایی را در مورد مشکل ارائه دهند.

متداول‌ترین دلیل شکست بسته PyInstaller این است که PyInstaller یک فایل مورد نیاز را باندل نکرده است. چنین فایل های گم شده به چند دسته تقسیم می شوند:

  • واردات پنهان یا گمشده: گاهی اوقات PyInstaller نمی تواند واردات یک بسته یا کتابخانه را تشخیص دهد، معمولاً به این دلیل که به صورت پویا وارد می شود. در این مورد، باید بسته یا کتابخانه را به صورت دستی مشخص کنید.
  • فایل‌های مستقل از دست رفته: اگر برنامه به فایل‌های داده خارجی بستگی دارد که باید با برنامه همراه شوند، PyInstaller راهی برای اطلاع از آن ندارد. باید به صورت دستی فایل هایی را که قرار است اضافه کنید مشخص کنید.
  • فقدان باینری: در اینجا دوباره، اگر برنامه شما به یک باینری خارجی مانند یک DLL. وابسته است که PyInstaller نمی تواند آن را شناسایی کند، باید آن را به صورت دستی اضافه کنید.

خبر خوب این است که PyInstaller یک راه آسان برای مقابله با مشکلات فوق ارائه می دهد. فایل .spec ایجاد شده توسط PyInstaller شامل فیلدهایی است که می توانیم برای ارائه جزئیاتی که PyInstaller از دست داده است پر کنیم.

ویرایش فایل مشخصات

برای بسته‌بندی فایل‌های اضافی مورد نیاز، فایل .spec را در یک ویرایشگر متن باز کنید و به دنبال تعریف شی Analysis بگردید. چندین پارامتر ارسال شده به Analysis لیست‌های خالی هستند، اما می‌توانید آنها را ویرایش کنید تا جزئیات گمشده را مشخص کنید:

  • hiddenimports برای واردات پنهان یا گمشده: یک یا چند رشته را با نام کتابخانه‌هایی که می‌خواهید با برنامه‌تان اضافه شود به این فهرست اضافه کنید. برای مثال، اگر می‌خواهید pandas و bokeh را اضافه کنید، آن را به‌عنوان ['pandas','bokeh'] مشخص می‌کنید. توجه داشته باشید که کتابخانه‌های مورد نظر باید در همان نمونه‌ای از Python که در آن PyInstaller را اجرا می‌کنید، نصب شوند – یک استدلال خوب دیگر برای استفاده از یک محیط مجازی.
  • داده‌ها برای فایل‌های مستقل از دست رفته: در اینجا یک یا چند مشخصات برای فایل‌های درخت پروژه خود که می‌خواهید با پروژه خود اضافه کنید، اضافه کنید. هر فایل باید به صورت یک تاپل ارسال شود که نشان دهنده مسیر نسبی فایل در دایرکتوری پروژه شما و مسیر نسبی در دایرکتوری توزیع است که می خواهید فایل را در آن قرار دهید. به عنوان مثال، اگر فایلی به نام ./models/mainmodel.dat داشتید که می‌خواستید آن را به برنامه خود اضافه کنید، و می‌خواستید آن را در یک زیرشاخه منطبق در فهرست توزیع خود قرار دهید، از ('./models/mainmodel.dat','./models') به عنوان یک ورودی در فهرست hiddenimports استفاده کنید. توجه داشته باشید که برای تعیین بیش از یک فایل می‌توانید از علامت‌های عام glob استفاده کنید.
  • باینری‌ها برای باینری‌های مستقل از دست رفته: مانند داده‌ها، می‌توانید از باینری برای ارسال فهرستی از تاپل هایی که مکان های باینری ها را در درخت پروژه و مقصد آنها را در فهرست توزیع مشخص می کنند. باز هم می‌توانید از علامت‌های عام به سبک glob
  • استفاده کنید

به خاطر داشته باشید که هر یک از لیست‌های ارسال شده به Analysis را می‌توان در فایل .spec به صورت برنامه‌نویسی زودتر ایجاد کرد. پس از همه، فایل .spec فقط یک اسکریپت پایتون با نام دیگری است.

بعد از ایجاد تغییرات در فایل .spec، PyInstaller را مجدداً اجرا کنید تا بسته را بازسازی کنید. با این حال، از این پس، مطمئن شوید که فایل .spec تغییر یافته را به عنوان پارامتر ارسال کنید (به عنوان مثال، pyinstaller myapp.spec). فایل اجرایی را مانند قبل تست کنید. اگر چیزی هنوز خراب است، می‌توانید فایل .spec را دوباره ویرایش کنید و این فرآیند را تا زمانی که همه چیز کار کند تکرار کنید.

در نهایت، وقتی راضی بودید که همه چیز طبق خواسته‌تان کار می‌کند، ممکن است بخواهید فایل  .spec را ویرایش کنید تا از نمایش پنجره خط فرمان برنامه بسته‌بندی‌شده خود در هنگام راه‌اندازی جلوگیری کنید. در تنظیمات شی EXE در فایل .spec، console=False را تنظیم کنید. اگر برنامه شما دارای رابط کاربری گرافیکی باشد و نمی‌خواهید یک پنجره خط فرمان جعلی که کاربران را گمراه کند، سرکوب کنسول مفید است. البته، اگر برنامه شما به خط فرمان نیاز دارد، این تنظیم را تغییر ندهید.

تصفیه بسته PyInstaller

وقتی برنامه خود را با PyInstaller بسته بندی کردید و به درستی اجرا شد، کار بعدی که احتمالاً می خواهید انجام دهید این است که کمی آن را کاهش دهید. بسته های PyInstaller به شیک بودن معروف نیستند.

از آنجایی که پایتون یک زبان پویا است، پیش‌بینی آنچه در زمان اجرا توسط یک برنامه خاص مورد نیاز است، دشوار است. به همین دلیل، وقتی PyInstaller یک بسته را شناسایی می‌کند، همه چیز را در آن بسته شامل می‌شود، خواه واقعاً در زمان اجرا توسط برنامه شما استفاده شده باشد یا نه.

خبر خوب این است: PyInstaller مکانیزمی را برای حذف انتخابی کل بسته‌ها یا فضای نام منفرد در بسته‌ها دارد. به عنوان مثال، فرض کنید برنامه شما بسته foo را وارد می کند که شامل foo.bar و foo.bip است. اگر به درستی می دانید که برنامه شما فقط از منطق در foo.bar استفاده می کند، می توانید با خیال راحت foo.bip را حذف کنید و مقداری فضا ذخیره کنید.

برای انجام این کار، از پارامتر excludes استفاده می‌کنید که به شی Analysis در فایل .spec ارسال شده است. می‌توانید فهرستی از نام‌ها – ماژول‌های سطح بالا یا فضاهای نام نقطه‌دار – را برای حذف از بسته خود ارسال کنید. به عنوان مثال، برای حذف foo.bip، به سادگی می‌توانید ['foo.bip'] را مشخص کنید.

PyInstaller دایرکتوری قابل تحویل را ایجاد می کند.

PyInstaller دایرکتوری قابل تحویل را ایجاد می کند. به دلیل تعداد زیاد فایل‌ها در فهرست، ممکن است از یک پروژه نصب‌کننده شخص ثالث مانند NSIS برای بسته‌بندی دایرکتوری در یک بایگانی خود استخراج‌کننده و ایجاد خودکار میان‌بر برای فایل اجرایی استفاده شود.

یک استثناء رایج، مجموعه‌های آزمایشی است. اگر بسته ای که برنامه شما وارد می کند دارای مجموعه آزمایشی باشد، بسته آزمایشی ممکن است در بسته PyInstaller شما گنجانده شود. مگر اینکه واقعاً مجموعه آزمایشی را در برنامه مستقر خود اجرا کنید، می‌توانید با خیال راحت آن را حذف کنید.

یک استثنای رایج دیگر tkinter است، کتابخانه Python برای ایجاد رابط‌های کاربری گرافیکی ساده بین پلتفرمی. به‌طور پیش‌فرض tkinter نباید گنجانده شود (نسخه‌های قدیمی‌تر PyInstaller به طور پیش‌فرض شامل آن می‌شدند)، اما اگر چنین است، می‌توانید با افزودن 'tkinter' آن را حذف کنید. فهرست استثنا. حذف tkinter اندازه بسته را حدود ۷ مگابایت کاهش می دهد.

به خاطر داشته باشید که بسته های ایجاد شده با استفاده از موارد استثنا باید کاملاً آزمایش شوند. اگر در نهایت عملکردی را که در سناریوهای آینده مورد استفاده قرار می‌گیرد حذف کنید، برنامه شما خراب می‌شود.

نکات PyInstaller

اجازه دهید با بهترین روش‌ها و اشتباهاتی که در هنگام استفاده از PyInstaller از آنها اجتناب کنید، پایان دهیم.

  • بسته PyInstaller خود را بر روی سیستم عامل استقرار بسازید: PyInstaller از ساخت‌های چند پلتفرمی پشتیبانی نمی‌کند. اگر نیاز به استقرار برنامه پایتون مستقل خود در سیستم‌های MacOS، Linux و Windows دارید، باید PyInstaller را نصب کنید و نسخه‌های جداگانه‌ای از برنامه را روی هر یک از این سیستم‌عامل‌ها بسازید.
  • پکیج PyInstaller خود را همزمان با توسعه برنامه خود بسازید: به محض اینکه فهمیدید پروژه خود را با PyInstaller اجرا می‌کنید، فایل .spec خود را بسازید و شروع به اصلاح آن کنید. بسته PyInstaller به موازات توسعه برنامه شما. به این ترتیب، می‌توانید در حین حرکت، موارد استثنا یا مواردی را اضافه کنید، و نحوه استقرار ویژگی‌های جدید با برنامه را در حین نوشتن آزمایش کنید.
  • برای برنامه‌های دارای نقطه ورودی ماژول، یک خرد بسازید: برخی از برنامه‌ها از یک ماژول به عنوان نقطه ورودی استفاده می‌کنند، برای مثال با داشتن یک فایل __main__.py که فراخوانی می‌شود. هنگامی که ماژول وارد می شود. PyInstaller مکانیزمی برای استفاده از چنین ماژولی به عنوان نقطه ورود ندارد. برای انجام این کار، یک فایل “خرد” ایجاد کنید—یک فایل .py در بالای صفحه پروژه شما که مراحل اجرای برنامه شما را مشابه محتویات فایل __main__.py انجام می دهد. سپس برای انجام تجزیه و تحلیل، PyInstaller را وارد کنید.
  • از حالت –onefile PyInstaller استفاده نکنید: PyInstaller شامل یک سوئیچ خط فرمان، --onefile است که کل برنامه شما را در یک فایل اجرایی خود استخراج می‌کند. . این یک ایده عالی به نظر می رسد – شما فقط باید یک فایل را تحویل دهید! – اما مشکلاتی دارد. در ویندوز، هر زمان که برنامه را اجرا می کنید، ابتدا باید تمام فایل های موجود در فایل اجرایی را در یک پوشه موقت باز کنید. اگر برنامه بزرگ باشد (مثلاً ۲۰۰ مگابایت)، باز کردن بسته بندی می تواند به معنای تاخیر چند ثانیه ای باشد. برای حل این مشکل، به جای آن از حالت پیش‌فرض تک فهرستی استفاده کنید و فقط همه چیز را به عنوان یک فایل zip جمع کنید.
  • ایجاد یک نصب کننده برای برنامه PyInstaller خود: اگر می‌خواهید روشی غیر از فایل .zip یا توزیع تک فایلی برای استقرار برنامه خود داشته باشید، از یک ابزار نصب مانند منبع باز استفاده کنید < a href="https://nsis.sourceforge.io/Main_Page" rel="nofollow">سیستم نصب Nullsoft Scriptable. سربار بسیار کمی به اندازه قابل تحویل اضافه می کند و به شما امکان می دهد بسیاری از جنبه های فرآیند نصب را پیکربندی کنید، مانند ایجاد میانبر برای فایل اجرایی خود.
  • از امضای کد در ویندوز برای علامت‌گذاری فایل‌های اجرایی تولید شده استفاده کنید: اگر گواهی امضای کد دارید و می‌خواهید از آن برای امضای پروژه‌ای که توسط PyInstaller ایجاد شده است استفاده کنید تا از پرچم‌گذاری آن به‌عنوان بدافزار جلوگیری کنید، یک دستور العمل برای انجام این کار وجود دارد. برای صرفه جویی در زمان، می توانید فرآیند امضا را در فایل .spec.
  • پروژه ادغام کنید

  • انتظار افزایش سرعت نداشته باشید: PyInstaller یک سیستم بسته‌بندی است، نه یک کامپایلر یا بهینه‌ساز. کد بسته بندی شده با PyInstaller سریعتر از زمانی که در سیستم اصلی اجرا می شود اجرا نمی شود. اگر می‌خواهید سرعت کد پایتون را افزایش دهید، از یک کتابخانه C-accelerated مناسب برای کار یا پروژه‌ای مانند Cython استفاده کنید.