کامپایل و حفاظت از پایتون؛ Cython

کامپایل و حفاظت از پایتون
کامپایل و حفاظت از پایتون

پایتون زبان برنامه‌نویسی ساده اما قدرتمندی است و سرویس‌ها،‌ اسکریپت‌ها و محصولات متنوعی بر پایه پایتون نوشته شده‌اند.

پایتون (درحالت عادی) بر خلاف زبانی مثل ++C برای اجراشدن، کامپایل نمی‌شود و اصطلاحا تفسیری یا Interpreted است. شاید تعبیر خیلی صحیحی نباشد اما برای نزدیک‌شدن ذهن: برای اجرای پایتون، مفسر اسکریپت را خط به خط اجرا می‌کند تا اسکریپت تمام شود (شاید هم نشود!)؛ لود کتابخانه‌ها، ساختن Thread، اتصال به دیتابیس و ... همگی به همین صورت انجام می‌شود.

حالا در نظر بگیرید بنا به دلایلی نخواهید از یک اسکریپت خام پایتون استفاده کنید. مثلا کد/ماژول پایتون شما قرار است در سروری بکارگیری شود که مدیریت آن با شما نیست، طبیعتا در این حالت باید از کد خود حفاظت کنید. فایل‌هایی هم که بصورت pyc. در می‌آیند در این زمینه خیلی مفید نخواهد بود...حسب تجربه :)

محافظت از سورس‌کد پایتون کار پیچیده‌ای نیست و ابزار یا (بهتر بگویم) کتابخانه‌ای وجود دارد به اسم Cython.

۱. معرفی Cython

کتابخانه Cython کد یا ماژول‌های پایتونی شما را تبدیل به C می‌کند و این سورس‌کدهای C به فایل‌های باینری و کتابخانه‌های اشتراکی کامپایل می‌شوند؛ کتابخانه اشتراکی یا Shared Objects در لینوکس so ها هستند و در ویندوز همان DLL معروف.
خبر خوب اینکه راهی مستقیم برای تبدیل کتابخانه‌های اشتراکی به سورس‌کد نداریم.


۲. نصب Cython

نصب Cython به سادگی با pip انجام می‌شود:

pip3 install cython


۳. یک فایل compile.py بسازید

در کنار ماژول‌ و سورس‌کد پایتون یک فایل با نام compile.py با محتویات زیر بسازید. اسم فایل هم لزوما نباید compile.py باشد.

from distutils.core import setup
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

ext_modules = [
    Extension(&quotmymodule1&quot,  [&quotmymodule1.py&quot]),
    Extension(&quotmymodule2&quot,  [&quotmymodule2.py&quot]),
    Extension(&quotmymodule2&quot,  [&quotmymodule3.py&quot]),
]

setup(
    name = 'My Program Name',
    cmdclass = {'build_ext': build_ext},
    ext_modules = ext_modules
)


۴. اجرا و کامپایل

برای اجرا، کامپایل و ساخت فایل‌های so دستور زیر را اجرا کنید:

python3 compile.py build_ext --inplace
کامپایل سورس‌کد پایتون
کامپایل سورس‌کد پایتون


پس از اجرای این دستور، فایل‌های زیر ساخته خواهند شد:

فایل‌های ساخته‌شده
فایل‌های ساخته‌شده

فایل so بصورت زیر نام‌گذاری شده:

  • عنوان ماژول
  • ورژن پایتون استفاده‌شده
  • معماری سیستم‌عامل و پردازنده
  • پلتفرم مورد استفاده


چه اتفاقی افتاد؟

ابتدا سورس‌کد پایتون تبدیل به C شد (کد میانی) و بعد کامپایلرِ C (مثلا gcc) این کد C را تبدیل به so کرد. برای سیستم‌های ویندوزی تست نکردم اما قاعدتا باید DLL تولید کند.


۵. نحوه استفاده

برای استفاده نیازی به سورس‌کد پایتون (py) و کدهای C نیست. فایل‌های so کافی هستند. استفاده از so هم عین py است، یعنی اگر قبلا ماژولی را (کامپایل‌نشده، همان py) بصورت زیر استفاده می‌کردید:

from parser import cache

فایل so ساخته‌شده را جایگزین py کنید و کار دیگری لازم نیست.


۶. چندنکته

در اصل قضیه تفاوتی ایجاد نشده است. شما همان پایتون را اجرا می‌کنید و فقط بجای ماژول/کدی که قبلا داشتید، کامپایل‌شده آن را استفاده و import می‌کنید.

اگر در سورس‌کد پایتون شما کتابخانه‌ای استفاده شده (مثلا از yaml) برای استفاده so در سیستم دیگر، باید این کتابخانه‌ها در سیستم دیگر هم نصب شده باشند.

اگر از لینوکس استفاده می‌کنید، حتما باید پکیج gcc برای کامپایل نصب شده باشد.

من روی Ubuntu 18.04 کامپایل کردم و در CentOS 7 به خوبی کار کرد، طبیعی هم بود :)

برای کامپایل با پایتون ۳.۷ خطاهای عجیبی بوجود آمد، به همین دلیل ابتدا با پایتون ۳.۶ کامپایل کردم تا کدهای C ساخته شوند و مجدد با پایتون ۳.۷ اجرا شد :||

هرچند پشتیانی از پایتون ۲ تمام شده اما رویه استفاده از Cython به همین صورت است.



توضیح: نوشتار از این مقاله گرفته شده است.