نحوه‌ی ساخت پکیج در پایتون

python packaging

گاهی اوقات ممکن است شما برنامه‌ای با تعداد زیادی ماژول نوشته باشید (ماژول می‌تواند یک فایل ساده شامل تعدادی کلاس باشد) و قصد دارید تمام آن‌ها را به یک بسته‌ی واحد (package) تبدیل کنید. زمانی که تعداد این ماژول‌ها (فایل‌ها) در پروژه‌ای زیاد شود، بهتر است ماژول‌های مشابه را در یک دایرکتوری (directory) قرار داده و مجموع تمام دایرکتوری ها را به یک بسته‌ی واحد تبدیل کنیم. در این مقاله قصد داریم نحوه‌ی ساخت یک بسته‌ی بسیار ساده در پایتون را بررسی کنیم.

مراحل ساخت یک بسته

شاید بتوان گفت مراحل ساخت یک بسته در پایتون ساده است. این مراحل عبارتند از:

  • ساخت یک دایرکتوری (پوشه) و اختصاص نام بسته‌ی مورد نظر خود به آن
  • قرار دادن ماژول‌ها در دایرکتوری
  • ساخت فایل __init__ در دایرکتوری

توجه کنید که ایجاد فایل __init__ با پسوند py برای ساخت یک بسته ضروری است. به دلیل اینکه در صورت وجود این فایل در دایرکتوری مورد نظر، پایتون تشخیص می‌دهد که آن یک دایرکتوری معمولی نیست؛ بلکه یک دایرکتوری برای یک بسته‌ی پایتون است. ما در این فایل دستوراتی به منظور import کردن کلاس‌های بسته‌ی خود را می‌نویسیم.

مثال ساده‌ای از ساخت یک بسته‌ی پایتون

در این بخش می‌خواهیم بسته‌ای با نام animals بسازیم. این بسته شامل دو فایل (ماژول) با نام‌های mammals و birds بوده که هر کدام به ترتیب دارای کلاس‌های Mammals و Birds درون خود هستند. پس گام به گام پیش می‌رویم.

۱- ساخت دایرکتوریِ بسته

در ابتدا یک دایرکتوری با نام animals در سیستم خود ایجاد کرده و وارد آن می‌شویم. با استفاده از دستور زیر نیز می‌توانید این کار را در خط فرمان سیستم‌های unix-like انجام دهید.

mkdir animals/
cd animals/

۲- افزودن کلاس‌ها

حال نوبت به ایجاد دو کلاس Mammals و Birds در ماژول‌های mammals و birds است. در ابتدا یک فایل با نام mammals.py در دایرکتوری animals ساخته و کد زیر را در آن می‌نویسیم.

class Mammals:
    def __init__(self):
        ''' Constructor for this class. '''
        # Create some member animals
        self.members = ['Tiger', 'Elephant', 'Wild Cat', 'Fox']
 
 
    def printMembers(self):
        print('Printing members of the Mammals class')
        for member in self.members:
            print('\t%s ' % member)

این کلاس دارای یک لیست با نام members بوده که نام چندین حیوان پستاندار در آن نوشته شده است. همچنین یک تابع با نام printMembers در این کلاس وجود دارد که در آن با استفاده از دستور print نام این حیوانات برای کاربر نمایش داده می‌شود. به یاد داشته باشید، زمانی که ما بسته‌ی پایتونی را می‌سازیم، نیازی به اجرای کلاس‌های ساخته شده در آن نداریم. بلکه در اینجا ما تنها به import کلاس‌های ساخته شده نیاز داریم که در برنامه‌ی جدیدمان می‌خواهیم بنویسیم.

در ادامه فایلی با نام birds.py در همان دایرکتوری animals می‌سازیم و کد زیر را در آن می‌نویسیم.

class Birds:
    def __init__(self):
        ''' Constructor for this class. '''
        # Create some member animals
        self.members = ['Sparrow', 'Robin', 'Duck', 'Penguin']
 
 
    def printMembers(self):
        print('Printing members of the Birds class')
        for member in self.members:
           print('\t%s ' % member)

کد نوشته شده در این فایل، عملکردی کاملا مشابه با فایل mammals.py دارد.

۳- افزودن فایل __init__

در مرحله‌ی آخر لازم است تا یک فایل __init__ با پسوند py در دایرکتوری animals ایجاد نماییم. پس از ساخت این فایل، کد زیر را در آن می‌نویسیم.

from .mammals import Mammals
from .birds import Birds

نقطه (.) به همین مکان از دایرکتوری اشاره می‌کند.

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

برای تست عملکرد این بسته، یک فایل پایتون جدید در خارج از دایرکتوری animals ساخته (همان مکانی که دایرکتوری animals را در آن ساخته‌ایم) و از کلاس‌های بسته‌ی جدید خود در آن استفاده می‌کنیم.

# Import classes from your brand new package
from animals import Mammals
from animals import Birds
 
# Create an object of Mammals class & call a method of it
myMammal = Mammals()
myMammal.printMembers()
 
# Create an object of Birds class & call a method of it
myBird = Birds()
myBird.printMembers()

پس از اجرای این برنامه، خروجی زیر نمایش داده می‌شود:

Printing members of the Mammals class
    Tiger 
    Elephant 
    Wild Cat 
    Fox 
Printing members of the Birds class
    Sparrow 
    Robin 
    Duck 
    Penguin 

همانطور که مشخص است از متد‌های printMembers موجود در دو کلاس Mammals و Birds استفاده کرده و لیست موجود در آن‌ها را چاپ نموده‌ایم.

استفاده از بسته در کل سیستم

در این مثال ما تنها می‌توانیم از این بسته در برنامه‌هایی که در یک مسیر مشخص می‌نویسیم (همان مسیری که بسته‌ی animals را در آن ساختیم) استفاده کنیم. اما اگر بخواهیم اصطلاحا این بسته را روی سیستم نصب کنیم تا بتوان از آن در کل سیستم استفاده نمود باید چه کاری انجام دهیم؟ زمانی که ما از دستور import در برنامه‌ی خود استفاده می‌کنیم، پایتون این دستور را به صورت زیر تفسیر می‌کند:

  • به دنبال نام بسته‌ی import شده در کتابخانه‌های داخلی خود می‌گردد (مانند کتابخانه‌های os و sys).
  • به دنبال فایل یا پوشه‌ای همنام با بسته‌ی import شده در همان مسیر جاری می‌گردد.
  • به دنبال فایل یا پوشه‌ای همنام با بسته‌ی import شده در مسیر site-packages می‌گردد.

شاید بدانید که نصب یک بسته‌ی پایتون بر روی سیستم، چیزی بیش از کپی کردن یک سری فایل در یک مسیر مشخص نمی‌باشد. مسیری که بسته‌های پایتون در آن نصب می‌شوند، site-packages نام دارد. ما با اجرای دستور زیر در خط فرمان سیستم خود، می‌توانیم آدرس دقیق این مسیر را بدست آوریم.

python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"
# Output on my system:
# /usr/lib/python3.6/site-packages

ممکن است این خروجی بر روی سیستم شما متفاوت باشد.

فایلی با نام setup.py در همان مکانی که دایرکتوری animals را در آن ایجاد کردیم، ساخته و کد زیر را درون آن می‌نویسیم.

from setuptools import setup
setup(
  name = 'animals',
  version = '0.1',
  description= 'Animals Package',
  author = 'Moein Babapour',
  packages=['animals']

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

sudo python setup.py install
# or
sudo python setup.py develop

بدین ترتیب از این پس شما می‌توانید به راحتی در هر مکان از سیستم خود، از بسته‌ای که ساخته‌اید استفاده کنید. این دو دستور عملکردی تقریبا مشابه دارند و هر دو فایلی را در مسیر site-packages ایجاد می‌کنند. با این تفاوت که دستور اول، ابتدا به نوعی یک کپی از ماژول‌های ما ساخته و آن‌ها را در آن مسیر نصب می‌کند؛ در حالی که با اجرای دستور دوم، درون فایل ایجاد شده در site-packages (فایل animals.egg-link)، آدرس مسیری نوشته شده است که بسته‌ی ما در آن‌جا قرار دارد. بنابراین در حالت دوم لازم نیست تا پس از هر بار تغییر محتویات بسته‌ی خود، آن را install کنیم. (در صورتی که در حال توسعه‌ی بسته‌ی خود می‌باشید، پیشنهاد می‌شود از دستور دوم استفاده کنید).

این مثال، تنها نمونه‌ای ساده از چگونگی ساخت یک بسته‌ی پایتون و نحوه‌ی استفاده از آن بود. شما می‌توانید به همین ترتیب ماژول‌های بیشتری ساخته و از کلاس‌های بیشتری در بسته‌ی خود استفاده کرده و قابلیت‌های متنوعی به آن اضافه نمایید.

2 دیدگاه On نحوه‌ی ساخت پکیج در پایتون

  • سلام.
    ممنون از توضیحات شما. من پکیج را تولید و نصب کردم. در پروژه ای که پکیج ایجاد شده است، می توانم پکیج را استفاده کنم اما وقتی یک پروژه جدید میسازم پکیج را نمیشناسد. ممنون میشوم پاسخ را به ایمیل بنده بفرستید و بنده را راهنمایی کنید.

جوابی بنویسید:

آدرس ایمیل شما به صورت عمومی منتشر نخواهد شد.