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() بازنویسی می‌شوند.

The special global variables __name__, __spec__, __file__, __loader__ and __package__ are set in the globals dictionary before the module code is executed. (Note that this is a minimal set of variables - other variables may be set implicitly as an interpreter implementation detail.)

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

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

__file__, __loader__ and __package__ are set as normal based on the module spec.

اگر آرگومان 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: The global variable __cached__ is no longer set.

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

Execute the code at the named filesystem location and return the resulting module's globals dictionary. As with a script name supplied to the CPython command line, path_name may refer to a Python source file, a compiled bytecode file or a valid sys.path entry containing a __main__ module (e.g. a zipfile containing a top-level __main__.py file).

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

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

The special global variables __name__, __spec__, __file__, __loader__ and __package__ are set in the globals dictionary before the module code is executed. (Note that this is a minimal set of variables - other variables may be set implicitly as an interpreter implementation detail.)

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

If path_name directly references a script file (whether as source or as precompiled byte code), then __file__ will be set to path_name, and __spec__, __loader__ and __package__ will all be set to None.

If path_name is a reference to a valid sys.path entry, then __spec__ will be set appropriately for the imported __main__ module (that is, __spec__.name will always be __main__). __file__, __loader__ and __package__ will be set as normal based on the module spec.

A number of alterations are also made to the sys module. Firstly, sys.path may be altered as described above. sys.argv[0] is updated with the value of path_name and sys.modules[__name__] is updated with a temporary module object for the module being executed. All modifications to items in sys are reverted before the function returns.

توجه داشته باشید که برخلاف 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: The global variable __cached__ is no longer set.

همچنین ملاحظه نمائید

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

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

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

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

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

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

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

تابع importlib.import_module()