تفاوت بین فایل های pyc, pyd و pyo در پایتون چیست؟

امیرحسین بیگدلو 12 ماه قبل

 

در این مقاله ما تفاوت بین فایل‌های pyc, pyd و pyo را بررسی خواهیم کرد و میبینیم که چطور بایت‌کدی که در این فایل‌ها ذخیره شده است، توسط دیگر برنامه‌های پایتونی استفاده میشود.

 

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

 

 

 #  بایت‌کد و ماشین مجازی پایتون

پایتون دارای یک مفسر داخلی است که میتواند مستقیما به عنوان یک ابزار تعاملی(REPL) از کامندلاین مورد استفاده قرار گیرد. همچنین میتوانید کدهایتان را در اسکریپت‌ نوشته و توسط مفسر پایتون اجرا کنید. در هر دو مورد، مفسر کد شما را تجزیه کرده و آن را به بایت‌کد کامپایل میکند. سپس کد کامپایل شده را توسط ماشین مجازی پایتون(Python Virtual Machine) اجرا میکند. بایت کد دستورالعمل‌های سطح پایینی است که کامپیوتر میتواند بفهمد.

 

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

 

پایتون در زمانی که کدهای نوشته شده را به بایت‌کد تبدیل میکند، بسته به نیاز خود میتوانید فایل‌های pyc, pyd یا pyo را ایجاد کند. تبدیل کد به بایت‌کد بسیار مهم است. اگر این تبدیل اتفاق نیفتد، سیستم عامل نمیتواند کد را اجرا کند.

 

مقاله پیشنهادی: پایتون سریعتر با PyPy

 

 #  فایل‌های pyc در پایتون

ابتدا فایل‌های pyc را بررسی میکنیم. فایل‌های pyc به طور اتوماتیک توسط مفسر زمانی ایجاد میشوند که یک ماژول را import کرده باشید. این کار باعث افزایش سرعت ایمپورت‌های بعدی آن ماژول خواهد شد. بنابراین فایل‌های pyc زمانی ایجاد میشوند که در یک فایل py ماژول دیگری را ایمپورت کرده باشید.

 

در پایین ماژولی داریم که قرار است بعدا آن را ایمپورت کنیم. این ماژول فاکتوریل را حساب میکند:

# math_helpers.py

# a function that computes the nth factorial, e.g. factorial(2)
def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n - 1)

# a main function that uses our factorial function defined above
def main():
    print("I am the factorial helper")
    print("you can call factorial(number) where number is any integer")
    print("for example, calling factorial(5) gives the result:")
    print(factorial(5))

# this runs when the script is called from the command line
if __name__ == '__main__':
    main()

 

حالا اگر این ماژول را توسط کامندلاین با دستور python math_helpers.py اجرا کنید، هیچ فایل pyc تولید نخواهد شد.

 

اما اگر این ماژول را در جای دیگری ایمپورت کنیم، نتیجه متفاوت خواهد بود. در کد پایین، ماژول بالا را ایمپورت میکنیم:

# computations.py

# import from the math_helpers module
from math_helpers import factorial

# a function that makes use of the imported function
def main():
    print("Python can compute things easily from the REPL")
    print("for example, just write : 4 * 5")
    print("and you get: 20.")
    print("Computing things is easier when you use helpers")
    print("Here we use the factorial helper to find the factorial of 6")
    print(factorial(6))

# this runs when the script is called from the command line
if __name__ == '__main__':
    main()

 

حالا این کد را با دستور python computations.py اجرا کنید. نه تنها این کد به خوبی اجرا شده و نتیجه را نشان میدهد، بلکه متوجه میشویم که فایل math_helpers.pyc نیز ایجاد شده است. این اتفاق به خاطر این است که در ماژول computations، ماژول math_helpers را ایمپورت کرده ایم. برای سرعتدهی به ایمپورت‌های آینده این ماژول، پایتون بایت‌کد این ماژول را ایجاد کرده است.

 

وقتی سورس کد آپدیت میشود، فایل pyc نیز آپدیت میشود. این اتفاق هنگامی میفتد که زمان آپدیت شدن فایل py تغییر کند. این کار باعث میشود که پایتون اطمینان پیدا کند که بایت‌کد همیشه بروز است.

 

دقت کنید که استفاده از فایل‌های pyc فقط سرعت لود را افزایش میدهد و تاثیری در سرعت اجرای کد ندارد. این یعنی میتوانید کدتان را در یک ماژول کوچکتر ایمپورت کنید تا آماده‌سازی کدتان سریعتر اتفاق بیفتد.

 

از آنجایی که فایل‌های pyc وابسته به پلتفرم خاصی نیستند، میتوانند بین دستگاه‌های مختلف به اشتراک گذاشته شوند.

 

مقاله پیشنهادی: مشکل ایمپورت‌های حلقوی در پایتون

 

 #  فایل‌های pyo در پایتون

فایل‌های pyo هم در زمان ایمپورت شدن توسط ماژولی دیگر ساخته میشوند. همچنین اگر مفسر را با تنظیمات خاصی اجرا کنید،‌ فایل‌های pyo ایجاد خواهند شد. این نتظیمات خاص با آپشن o- به مفسر داده میشوند. در کد پایین از تنظیمات مفسر پایتون برای اجرا کدمان استفاده میکنیم. اول، ما یک ماژول داریم که یک متد lambda در خود دارد. در پایتون لامبدا همان فانکشن است اما نامی ندارد:

# lambdas.py

# a lambda that returns double whatever number we pass it
g = lambda x: x * 2

 

همانند مثال قبل نیاز است که این ماژول را در ماژول دیگری ایمپورت کنیم. در کد پایین ماژول lambdas.py را ایمپورت کرده و از لامبدا g استفاده میکنیم:

# using_lambdas.py

# import the lambdas module
import lambdas

# a main function in which we compute the double of 7
def main():
    print(lambdas.g(7))

# this executes when the module is invoked as a script at the command line
if __name__ == '__main__':
    main()

 

حالا به بخش مهم این مثال رسیدیم. به جای اینکه به طور عادی مفسر پایتون را صدا بزنید، اینکار را با o- انجام میدهیم. در این حالت بایت‌کدهای کوچکتری ایجاد خواهد شد.

 

برای اجرا کردن این کد در حالت optimizer به شکل زیر کار کنید:

$ python -O using_lambdas.py

 

بعد از اجرا، علاوه بر دریافت نتیجه، بایت‌کدهای جدیدی نیز برایمان ایجاد خواهد شد. این فایل به خاطر ایمپورت کردن lambdas.py در using_lambdas.py ایجاد شده است. از آنجایی که در حالت optimizer اینکار را انجام دادیم، فایلی با نام lambdas.pyo ایجاد شده است.

 

در حالت optimizer پایتون به طور کامل دستورات assert را نادیده میگیرد. همچنین، فایل‌های pyo جایگزین فایل‌های pyc میشوند که بدون بهینه سازی ایجاد میشدند. هر زمان که فایل‌های سورس کد پایتون آپدیت میشوند، فایل‌های pyo نیز آپدیت میشوند.

 

 

 #  فایل‌های pyd در پایتون

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

 

به منظور در دسترس قرار دادن این کتابخانه برای سایر برنامه های پایتون، باید به عنوان یک کتابخانه dynamic link پکیج شده باشد. Dynamic link libraries یا به طور مخفف DLL، کتابخانه هایی برای ویندوز هستند که در زمان اجرا برنامه‌های دیگر را فراخوانی میکنند. کتابخانه‌های DLL باعث ماژولارتر شدن و اجرای سریعتر برنامه‌ها میشوند. DLLها عملکردهای زیادی را در ویندوز ارائه میدهند.

 

فایل pyd یک DLL است شامل یک یا چند ماژول پایتونی است که قرار است توسط سایر کدهای پایتونی صدا زده شوند. برای ساخت این نوع از ماژول‌ها باید به طور دستی یک فایل با پسوند pyd ایجاد کنید مثلا example.pyd. در این ماژول باید یک فانکشن به نام PyInit_example ایجاد کنید. وقتی برنامه‌ای این ماژول را صدا میزند، PyInit_example اجرا خواهد شد.

 

دوره پیشنهادی: دوره سوم آموزش پروژه محور پایتون

 

 #  تفاوت بین این نوع فایل‌‌ها

هر چند که بین این سه نوع فایل شباهت‌هایی وجود دارد اما تفاوت‌های بزرگی نیز دارند. برای مثال، در حالی که فایل‌های pyc و pyo حاوی بایت کد پایتون هستند، اما تفاوت آنها در این است که فایل‌های pyo به لطف بهینه‌سازی‌های انجام‌شده توسط مفسر فشرده‌تر هستند.

 

pyd. با دو مورد قبلی متفاوت است زیرا یک DLL برای استفاده در سیستم عامل ویندوز است. دو نوع فایل دیگر را می توان در هر سیستم عاملی، نه فقط ویندوز، استفاده کرد.

 

با این حال، همه این فایل‌ها شامل کدهایی است که توسط سایر برنامه های پایتون فراخوانی و استفاده می شود.

 

 

 #  نتیجه گیری

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

مطالب مشابه



مونگارد