Extension and Embedding

از Pythoni.ca

پرش به: ناوبری, جستجو
این نوشته (Extension and Embedding) بخشی از کتاب عصر پایتون می باشد .
کتاب یک بایت از پایتون نکته ها و ترفند ها ماژول ها نمونه پروژه منابع آموزشینرم افزارهای جانبیکتابخانه‌های داخلی و خارجی پرسش و پاسخ

فهرست مندرجات

Extension and embedding چیست ؟

گسترش (extending) پایتون یک مبحث تخصصی پایتون برای گسترش و هرچه بهینه تر کردن عملکرد آن می باشد . قصد دارم تا نحوه گسترش و توسعه پایتون را با زبانهای C و ++C توضیح بدم و نیز در دروس آینده نحوه استفاده از پایتون و اشیا آن در سایر زبانهای برنامه نویسی مطرح خواهد شد . همونطور که قبلا هم اشاره شد پایتون همانند یک چسب کار ادغام و ربط دادن تکه های مختلف کد و برنامه را دارا می باشد و این ویژگی یکی از مهمترین و جذابترین بحث های مربوط به زبان برنامه نویسی پایتون است . اما دلیل این ویژگی این است که پایتون قابل گسترش و نیز درونی سازی با سایر زبانهای برنامه نویسی می باشد . یعنی می توان از کد ها و دستورات نوشته شده با سایر زبانها در داخل پایتون بهره برد یا برعکس از پایتون در زبانهای دیگر استفاده کرد . (مخصوصا زبان C) زمانی از پایتون برای فراخوانی کد نوشته شده در C استفاده می شود عمل توسعه (extending) و زمانی که از زبان C برای فراخوانی کد های پایتون استفاده می شود عمل درونی سازی یا (embedding) اتفاق می افتد . عمل توسعه پایتون در حقیقت همان نوشتن ماژول های جدید اما با زبانی چون C می باشد . با استفاده از این ویژگی می توان برنامه های بسیار قدرمتندی را به راحتی و سرعت اجرای زیاد نوشت . پایتون ارتباط بهتری با C برقرار می کند چون مفسر پایتون با این زبان نوشته شده است . این ویژگی معمولا برای ایجاد یک کاربرد و امکان جدید یا برقراری ارتباط با سخت افزار یا در مواقعی که سرعت پردازش و اجرا مهم باشد به کار برده می شود . برای نوشتن ماژول و توسعه پایتون شما به سورس مفسر پایتون و یک کامپایلر C نیاز خواهید داشت . لازم به ذکر است که اکثر توزیع های لینوکس همه فایل ها و کامپایلر مورد نیاز را دارا می باشند . بنابر این شما به همه سورس مفسر نیازمند نخواهید بود . در لینوکس مبتنی بر Red hat این بسته python-devel نام دارد که بصورت پیشفرض نصب می گردد . پایتون API های بسیار روشن و واضحی را برای استفاده از سیستم زمان اجرای (runtime) فراهم می کند این API ها تعدادی تابع برای برای مدیریت و استفاده از اشیا و داده های درونی (built-in) پایتون از طریق C و ++C فراهم می کند . برای اضافه کردن این API ها و برنامه نویسی ماژول برای پایتون باید فایل سرآیند <Python.h> را به برنامه خود اضافه کنید . این فایل header شامل فایل های سرآیند مربوط به هر دو زبان پایتون و C می باشد . برای مثال فایل های : stdio.h , string.h , errno.h , stdlib.h بنابراین دیگر نیازی به اضافه (include) کردن آنها نمی باشد . برای آشنایی با این API ها و توسعه پایتون می توانید به اینجا و اینجا مراجعه کنید :

نحوه نوشتن ماژول و ادامه این مبحث در درسهای آتی ادامه می یابد . فقط در ادامه یک نمونه مثال ساده مطرح می گردد .

نوشتن ماژول بصورت مستقیم

می خواهیم برنامه (ماژول) ساده ای را به زبان C بنویسم که کاری شبیه به تابع زیر را انجام می دهد :


تابع مورد نظر تصویر:code.png
def say_hello(name):
    print "Hello %s!" % name


ابتدا یک فایل متنی با نام hellomodule.c ایجاد و کد های زیر را درون آن کپی کنید :


hellomodule.c تصویر:code.png
#include <Python.h>
static PyObject* say_hello(PyObject* self, PyObject* args)
{
    const char* name;
    if (!PyArg_ParseTuple(args, "s", &name))
        return NULL;
    printf("Hello %s!\n", name);
    Py_RETURN_NONE;
}

static PyMethodDef HelloMethods[] =
{
     {"say_hello", say_hello, METH_VARARGS, "Greet somebody."},
     {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
inithello(void)
{
     (void) Py_InitModule("hello", HelloMethods);
}


اکنون برای ایجاد ماژول باید از یک برنامه کوچک به زبان پایتون استفاده کنید . فایلی را با نام setup.py ایجاد و کد های زیر را درون آن کپی کنید :


setup.py تصویر:code.png
from distutils.core import setup, Extension

module1 = Extension('hello', sources = ['hellomodule.c'])

setup (name = 'PackageName',
        version = '1.0',
        description = 'This is a test package',
        ext_modules = [module1])


اکنون با دستور زیر ماژول را ایجاد کنید :



تصویر:terminal.png
# python setup.py build


ماژولی با نام hello.so در داخل دایرکتوری build/lib.linux-i686-2.4 ایجاد می گردد . برای استفاده از این ماژول به مسیر فایل hello.so بروید و مفسر پایتون را اجرا کنید :


استفاده از ماژول تصویر:code.png
>>> import hello
>>> hello.say_hello("World")
Hello World!


همانطور که ملاحضه می کنید ماژول به درستی ایجاد شده است .

نوشتن ماژول با استفاده از SWIG

SWIG : SWIG که بر گرفته از عبارت Simple Warpper and Interface Generator می باشد یک ابزار خودکار برای نوشتن رابط بین پایتون و کتابخانه ها و کد های موجود C می باشد که توسط آقای David Beazley نوشته شده است . بنابراین برنامه نویس هیچگونه کد اضافی را نمی نویسد و می تواند بسادگی کد نوشته شده را تبدیل به ماژول پایتون کرده و از آن استفاده کند . SWIG کار خود را از طریق خواندن یک فایل رابط که شامل تعاریف متد ها و توابع می باشد انجام می دهد . و سپس بصورت خودکار تبدیل نوع داده ها ، چک کردن ایرادات کد ، ایجاد فایل C ، کامپایل فایل و ایجاد فایل ماژول را انجام می دهد . این ابزار بسیار مفید و کاری می باشد چون از طریق آن می توان کد های مختلف نوشته شده را به ماژول تبدیل کرد . بدون اینکه برنامه خاصی با روش های ویژه نوشته گردد . همان مثال بالا را این بار با استفاده از SWIG می نویسم . دقت کنید که ابتدا باید ابزار مورد نیاز نصب باشد . برای مثال ابتدا SWIG را نصب کنید .

دوباره فایل hellomodule.c را اینبار با کد زیر ایجاد کنید :


hellomodule.c تصویر:code.png
#include <stdio.h>

void say_hello(const char* name) {
    printf("Hello %s!\n", name);
}


این یک کد عادی نوشته شده با C و بدون تابع main می باشد (نیازی به تابع main نیست !) . سپس یک فایل دیگر با نام hello.i ایجاد و کد زیر را در آن بنویسید :


hello.i تصویر:code.png
%module hello
extern void say_hello(const char* name);


اکنون دستور زیر را در ترمینال وارد کنید :



تصویر:terminal.png
swig -python hello.i


این دستور دو فایل با نامهای hello.py و hello_warp.c را ایجاد می کند . مرحله بعدی عمل کامپایل می باشد با فرض اینکه مسیر فایل های include پایتون /usr/include/python2.4/ می باشد دستور زیر را وارد کنید :



تصویر:terminal.png
gcc -fpic -c hellomodule.c hello_wrap.c -I/usr/include/python2.4/


و سپس با دستور زیر عمل لینک را انجام دهید :



تصویر:terminal.png
gcc -shared hellomodule.o hello_wrap.o -o _hello.so



ماژول ایجاد شده و همانند حالت قبلی می توانید از آن استفاده کنید .

SWIG و ابزار هایی شبیه آن

Swig ابزار بسیار قدرتمندی می باشدکه می تواند ماژول هایی را برای زبانهای C# , Java , modula3 , perl , php , pike , python , ruby , tcl و ... ایجاد کند .

ابزارهای دیگری همانند SWIG موجود می باشند همانند SIP که وظیفه آن ارتباط دادن پایتون و Qt و KDE می باشد و توسط آقای Phil Thompson نوشته شده است .


SCXX : که به اختصار CXX نامیده می شود کار مشابهی را برای ++C انجام می دهد یعنی نوشتن ماژول پایتون با ++C و توسط آقای Gordon McMillan نوشته شده است . البته روشهای دیگری چون Pyrex یا ... نیز برای استفاده از ویژگی زبانهایی چون C در کد های پایتون موجود است که به مرور به همه آنها آشنا خواهیم شد .