runpy --- یافتن و اجرای ماژول‌های پایتون

کد منبع: Lib/runpy.py


ماژول runpy برای پیدا کردن و اجرای ماژول‌های پایتون بدون آنکه ابتدا آن‌ها را ایمپورت کند استفاده می‌شود. کاربرد اصلی آن پیاده‌سازی گزینه‌ی خط فرمان -m است که امکان پیدا کردن اسکریپت‌ها را با استفاده از فضای نام ماژول‌های پایتون به‌جای سامانه فایل‌بندی فراهم می‌کند.

توجه داشته باشید که این یک ماژول سندباکس نیست — تمام کدها در فرایند جاری اجرا می‌شوند و هرگونه اثر جانبی (مانند ایمپورت‌های نهانگاه‌شده‌ی سایر ماژول‌ها) پس از بازگشت توابع بر جای خواهد ماند.

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

ماژول runpy دو تابع ارائه می‌دهد:

runpy.run_module(mod_name, init_globals=None, run_name=None, alter_sys=False)

کد ماژول مشخص‌شده را اجرا می‌کند و دیکشنری سراسری‌های ماژول حاصل را برمی‌گرداند. کد ماژول ابتدا با استفاده از سازوکار استاندارد ایمپورت یافت می‌شود (برای جزئیات به PEP 302 مراجعه کنید) و سپس در یک فضای نام تازه‌ی ماژول اجرا می‌شود.

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

می‌توان از آرگومان دیکشنری اختیاری init_globals برای از پیش پر کردن دیکشنری سراسری‌های ماژول پیش از اجرای کد استفاده کرد. init_globals تغییر نخواهد کرد. اگر هر یک از متغیرهای سراسری خاص زیر در init_globals تعریف شده باشند، آن تعریف‌ها توسط run_module() بازنویسی می‌شوند.

متغیرهای سراسری خاص __name__، __spec__، __file__، __loader__ و __package__ پیش از اجرای کد ماژول در دیکشنری سراسری تنظیم می‌شوند. (توجه داشته باشید که این مجموعه کوچکی از متغیرها است؛ سایر متغیرها ممکن است به طور ضمنی به عنوان جزئیات پیاده‌سازی مفسر تنظیم شوند.)

__name__ هنگامی که این آرگومان اختیاری None نباشد، به run_name تنظیم می‌شود؛ اگر ماژول نام‌برده یک بسته باشد، به mod_name + '.__main__' و در غیر این صورت به آرگومان mod_name تنظیم می‌شود.

__spec__ برای ماژول واقعاً ایمپورت‌شده به‌طور مناسب تنظیم می‌شود (یعنی __spec__.name همیشه mod_name یا mod_name + '.__main__' خواهد بود، هرگز run_name نخواهد بود).

متغیرهای __file__، __loader__ و __package__ بر اساس مشخصه ماژول به طور عادی تنظیم می‌شوند.

اگر آرگومان alter_sys ارائه شود و به True ارزیابی شود، sys.argv[0] با مقدار __file__ به‌روزرسانی می‌شود و sys.modules[__name__] با یک شیء ماژول موقت برای ماژول در حال اجرا به‌روزرسانی می‌شود. هر دو sys.argv[0] و sys.modules[__name__] پیش از بازگشت تابع به مقادیر اصلی خود بازمی‌گردند.

توجه داشته باشید که این دستکاری sys نخ‌ایمن نیست. سایر نخ‌ها ممکن است ماژول تا حدی مقداردهی اولیه‌شده و همچنین فهرست تغییرکرده‌ی آرگومان‌ها را ببینند. توصیه می‌شود هنگام فراخوانی این تابع از کد چندنخی، ماژول sys دست‌نخورده باقی بماند.

همچنین ببینید

گزینه‌ی -m که قابلیت معادلی را از خط فرمان ارائه می‌دهد.

تغییر یافته در نسخه‌ی 3.1: توانایی اجرای بسته‌ها با جست‌وجوی زیرماژول __main__ اضافه شد.

تغییر یافته در نسخه‌ی 3.2: متغیر سراسری __cached__ اضافه شد (به PEP 3147 مراجعه کنید).

تغییر یافته در نسخه‌ی 3.4: به‌روزرسانی شد تا از ویژگی مشخصات ماژول که PEP 451 آن را افزوده است بهره ببرد. این امکان را می‌دهد که __cached__ برای ماژول‌هایی که به این روش اجرا می‌شوند به‌درستی تنظیم شود، و همچنین اطمینان حاصل می‌کند که نام واقعی ماژول همیشه به‌عنوان __spec__.name در دسترس است.

تغییر یافته در نسخه‌ی 3.12: تنظیم __cached__، __loader__ و __package__ منسوخ شده است. برای جایگزین‌ها به ModuleSpec مراجعه کنید.

تغییر یافته در نسخه‌ی 3.15: متغیر سراسری __cached__ دیگر تنظیم نمی‌شود.

runpy.run_path(path_name, init_globals=None, run_name=None)

کد را در موقعیت سامانه فایل‌بندی‌ای نام‌گذاری‌شده اجرا می‌کند و دیکشنری سراسری ماژول حاصل را برمی‌گرداند. همان‌طور که در مورد نام اسکریپت داده‌شده به خط فرمان CPython صدق می‌کند، file_path ممکن است به یک پرونده منبع پایتون، یک پرونده بایت‌کد کامپایل‌شده یا یک ورودی معتبر از sys.path اشاره کند که حاوی یک ماژول __main__ باشد (مثلاً یک پرونده زیپ حاوی یک پرونده __main__.py در سطح بالا).

برای یک اسکریپت ساده، کد تعیین‌شده به‌سادگی در یک فضای نام ماژول تازه اجرا می‌شود. برای یک ورودی معتبر sys.path (معمولاً یک پرونده zip یا پوشه)، ابتدا آن ورودی به ابتدای sys.path اضافه می‌شود. سپس تابع با استفاده از مسیر به‌روزشده، یک ماژول __main__ را جست‌وجو و اجرا می‌کند. توجه داشته باشید که اگر چنین ماژولی در مکان تعیین‌شده وجود نداشته باشد، هیچ محافظت ویژه‌ای در برابر فراخوانی یک ورودی __main__ موجود در جای دیگری از sys.path وجود ندارد.

می‌توان از آرگومان دیکشنری اختیاری init_globals برای پر کردن دیکشنری سراسری‌های ماژول پیش از اجرای کد استفاده کرد. init_globals تغییر نخواهد کرد. اگر هر یک از متغیرهای سراسری خاص زیر در init_globals تعریف شده باشند، آن تعریف‌ها توسط run_path() بازنویسی می‌شوند.

متغیرهای سراسری خاص __name__، __spec__، __file__، __loader__ و __package__ پیش از اجرای کد ماژول در دیکشنری سراسری تنظیم می‌شوند. (توجه داشته باشید که این مجموعه کوچکی از متغیرها است؛ سایر متغیرها ممکن است به طور ضمنی به عنوان جزئیات پیاده‌سازی مفسر تنظیم شوند.)

اگر این آرگومان اختیاری None نباشد، __name__ به run_name تنظیم می‌شود و در غیر این صورت به '<run_path>' تنظیم می‌شود.

اگر file_path مستقیماً به یک پرونده‌ی اسکریپت ارجاع دهد (چه به عنوان کد منبع و چه به عنوان بایت‌کد پیش‌کامپایل‌شده)، متغیر __file__ روی file_path تنظیم خواهد شد و __spec__، __loader__ و __package__ همگی روی None تنظیم خواهند شد.

اگر file_path ارجاعی به یک ورودی معتبر sys.path باشد، متغیر __spec__ به طور مناسب برای ماژول واردشده‌ی __main__ تنظیم خواهد شد (یعنی __spec__.name همیشه __main__ خواهد بود). متغیرهای __file__، __loader__ و __package__ بر اساس مشخصه ماژول به طور عادی تنظیم می‌شوند.

تغییراتی نیز در ماژول sys اعمال می‌شوند. نخست، ممکن است sys.path همان‌طور که در بالا توضیح داده شد تغییر کند. sys.argv[0] با مقدار file_path به‌روزرسانی می‌شود و sys.modules[__name__] با یک شیء ماژول موقتی برای ماژول در حال اجرا به‌روزرسانی می‌شود. پیش از بازگشت تابع، همه تغییرات در آیتم‌های sys بازگردانده می‌شوند.

توجه داشته باشید که برخلاف run_module()، تغییرات اعمال‌شده بر sys در این تابع اختیاری نیستند، زیرا این تنظیمات برای امکان‌پذیر ساختن اجرای مدخل‌های sys.path ضروری‌اند. از آن‌جا که محدودیت‌های ایمنی نخ همچنان برقرار است، استفاده از این تابع در کد چندنخی باید یا با قفل ایمپورت به‌صورت متوالی انجام شود یا به یک فرایند جداگانه محول گردد.

همچنین ببینید

گزینه‌های رابط برای عملکرد معادل در خط فرمان (python path/to/script).

اضافه شده در نسخه‌ی 3.2.

تغییر یافته در نسخه‌ی 3.4: به‌روزرسانی شد تا از ویژگی مشخصات ماژول که توسط PEP 451 اضافه شده است استفاده کند. این امر امکان می‌دهد که __cached__ در حالتی که __main__ به‌جای اجرای مستقیم، از یک ورودی معتبر sys.path ایمپورت می‌شود، به‌درستی تنظیم شود.

تغییر یافته در نسخه‌ی 3.12: تنظیم __cached__، __loader__ و __package__ منسوخ شده است.

تغییر یافته در نسخه‌ی 3.15: متغیر سراسری __cached__ دیگر تنظیم نمی‌شود.

همچنین ببینید

PEP 338 -- اجرای ماژول‌ها به‌عنوان اسکریپت

PEP توسط Nick Coghlan نوشته و پیاده‌سازی شده است.

PEP 366 -- ایمپورت‌های نسبی صریح در ماژول اصلی

PEP توسط Nick Coghlan نوشته و پیاده‌سازی شده است.

PEP 451 -- یک نوع ModuleSpec برای سامانه‌ی ایمپورت

PEP نوشته‌شده و پیاده‌سازی‌شده توسط اریک اسنو

خط فرمان و محیط - جزئیات خط فرمان CPython

تابع importlib.import_module()