دليل تعلم بايثون كيفية إنشاء الأصناف وتعريف الكائنات في بايثون 3


محمد الميداوي

بايثون لغةٌ برمجة كائنية (object-oriented programming language). تركز البرمجة الكائنية (OOP) على كتابة شيفرات قابلة لإعادة الاستخدام، على عكس البرمجة الإجرائية (procedural programming) التي تركز على كتابة تعليمات صريحة ومتسلسلة.

تتيح البرمجة الكائنية لمبرمجي بايثون كتابة شيفرات سهلة القراءة والصيانة، وهذا مفيد للغاية عند تطوير البرامج المُعقَّدة.

التمييز بين الأصناف والكائنات أحدُ المفاهيم الأساسية في البرمجة الكائنية، ويوضح التعريفان التاليان الفرق بين المفهومين:

  • الصنف - نموذج عام تُنسج على منواله كائنات يُنشِئها المبرمج. يُعرِّف الصنف مجموعةً من الخاصيات التي تميز أي كائن يُستنسَخ (instantiated) منه.
  • الكائن - نسخةٌ (instance) من الصنف، فهو تجسيد عملي للصنف داخل البرنامج.

تُستخدَم الأصناف لإنشاء أنماط، ثم تُستعمَل تلك الأنماط لإنشاء كائنات منها.

ستتعلم في هذا الدرس كيفيَّة إنشاء الأصناف والكائنات، وتهيئة الخاصيات باستخدام تابعٍ بانٍ (constructor method)، والعمل على أكثر من كائن من نفس الصنف.

كيفية-إنشاء-الأصناف-وتـعــريـــف-الكـائـنــــات.jpg

الأصناف

الأصناف هي نماذج عامة تُستخدم لإنشاء كائنات وسبق أن عرَّفناها آنفًا.

تُنشَأ الأصناف باستخدام الكلمة المفتاحية ‎class‎، بشكل مشابه [لتعريف الدوال](رابط المقالة 34) الذي يكون باستخدام الكلمة المفتاحية ‎def‎.

دعنا نعرّف صنفًا يسمى ‎Shark‎، ونجعل له تابعين مرتبطين به، swim و be_awesome:

class Shark:
    def swim(self):
        print("The shark is swimming.")

    def be_awesome(self):
        print("The shark is being awesome.")

تُسمَّى مثل هذه الدوال «توابعًا» (methods) لأنهما معرفتان داخل الصنف ‎Shark‎؛ أي أنهما دالتان تابعتان للصنف ‎Shark‎.

الوسيط الأول لهاتَين الدالتين هو ‎self‎، وهو مرجع إلى الكائنات التي يتم بناؤها من هذا الصنف. للإشارة إلى نُسخ (أو كائنات) من الصنف، يوضع ‎self‎ دائمًا في البداية، لكن يمكن أن تكون معه وسائط أخرى.

لا يؤدي تعريف الصنف ‎Shark‎ إلى إنشاء كائنات منه، وإنما يعرّف فقط النمط العام لتلك الكائنات، والتي يمكننا تعريفها لاحقًا. لذا، إذا نفّذت البرنامج أعلاه الآن، فلن يُعاد أي شيء.

الكائنات

الكائن هو نسخةٌ (instance) من صنف. ويمكن أن نأخذ الصنف ‎Shark‎ المُعرَّف أعلاه، ونستخدمه لإنشاء كائن يعدُّ نسخةً منه.

سننشئ كائنًا ‎Shark‎ يسمى ‎sammy‎:

sammy = Shark()

لقد أحلنا على الكائن ‎sammy‎ ناتج الباني ‎Shark()‎، والذي يعيد نسخةً من الصنف.

سنستخدم في الشيفرة التالية التابعين الخاصين بالكائن ‎sammy‎:

sammy = Shark()
sammy.swim()
sammy.be_awesome()

يستخدم الكائن ‎sammy‎ التابعين ‎swim()‎ و ‎be_awesome()‎، وقد استدعينَاهما باستعمال المعامل النقطي (‎.‎)، والذي يُستخدم للإشارة إلى خاصيات أو توابع الكائنات. في هذه الحالة، استدعينا تابعًا، لذلك استعملنا قوسين مثلما نفعل عند استدعاء دالة.

الكلمة ‎self‎ هي معامل يُمرّر إلى توابع الصنف ‎Shark‎، في المثال أعلاه، يمثّل ‎self‎ الكائن ‎sammy‎. يتيح المعامل ‎self‎ للتوابع الوصول إلى خاصيات الكائن الذي استُدعيت معه.

لاحظ أننا لم نمرر شيئًا داخل القوسين عند استدعاء التابع أعلاه، ذلك أنّ الكائن ‎sammy‎ يُمرّر تلقائيًا مع العامل النقطي.

البرنامج التالي يوضح لنا الأمر:

class Shark:
    def swim(self):
        print("The shark is swimming.")

    def be_awesome(self):
        print("The shark is being awesome.")


def main():
    sammy = Shark()
    sammy.swim()
    sammy.be_awesome()

if __name__ == "__main__":
    main()

لننفذ البرنامج لنرى ما سيحدث:

python shark.py

ستُطبع المخرجات التالية:

The shark is swimming.
The shark is being awesome.

في الشيفرة أعلاه، استدعى الكائن ‎sammy‎ التابعين ‎swim()‎ و ‎be_awesome()‎ في الدالة الرئيسية ‎main()‎.

الباني

يٌستخدم الباني (Constructor Method) لتهيئة البيانات الأولية، ويُنفَّذ لحظة إنشاء الكائن. في تعريف الصنف، يأخذ الباني الاسم ‎__init__‎، وهو أول تابع يُعرّف في الصنف، ويبدو كما يلي:

class Shark:
    def __init__(self):
        print("This is the constructor method.")

إذا أضفت التابع ‎__init__‎ إلى الصنف ‎Shark‎ في البرنامج أعلاه، فسيَطبع البرنامجُ المخرجات التالية:

This is the constructor method.
The shark is swimming.
The shark is being awesome.

يُنفَّذ الباني تلقائيًا، لذا يستخدمه مطورو بايثون لتهيئة أصنافهم.

سنُعدِّل الباني أعلاه، ونجعله يستخدم متغيرًا اسمه ‎name‎ سيمثّل اسم الكائن. في الشيفرة التالية، سيكون المتغير ‎name‎ المعامل المُمرَّر إلى الباني، ونحيل قيمته إلى الخاصية ‎self.name‎:

class Shark:
    def __init__(self, name):
        self.name = name

بعد ذلك، يمكننا تعديل السلاسل النصية في دوالنا للإشارة إلى اسم الصنف، على النحو التالي:

class Shark:
    def __init__(self, name):
        self.name = name

    def swim(self):
        # الإشارة إلى الاسم
        print(self.name + " is swimming.")

    def be_awesome(self):
        # الإشارة إلى الاسم
        print(self.name + " is being awesome.")

أخيرًا، يمكننا تعيين اسم الكائن ‎sammy‎ عند القيمة ‎"Sammy"‎ (أي قيمة الخاصية name) بتمريره إلى ‎Shark()‎ عند إنشائه:

class Shark:
    def __init__(self, name):
        self.name = name

    def swim(self):
        print(self.name + " is swimming.")

    def be_awesome(self):
        print(self.name + " is being awesome.")


def main():
    # Shark تعيين اسم كائن
    sammy = Shark("Sammy")
    sammy.swim()
    sammy.be_awesome()

if __name__ == "__main__":
    main()

عرّفنا التابع ‎__init__‎، والذي يقبل مُعاملين ‎self‎ و name (تذكر أن المعامل ‎self‎ يُمرر تلقائيا إلى التابع)، ثم عرّفنا متغيرًا فيه.

عند تنفيذ البرنامج:

python shark.py

سنحصل على:

Sammy is swimming.
Sammy is being awesome.

لقد طُبع الاسم الذي مرّرناه إلى الكائن. ونظرًا لأنّ الباني يُنفّذ تلقائيًا، فلست بحاجة إلى استدعائه بشكل صريح، فيكفي تمرير الوسائط بين القوسين التاليين لاسم الصنف عند إنشاء نسخة جديدة منه.

إذا أردت إضافة معامل آخر، مثل ‎age‎، فيمكن ذلك عبر تمريره إلى التابع ‎__init__‎:

class Shark:
    def __init__(self, name, age):
        self.name = name
        self.age = age

عند إنشاء الكائن ‎sammy‎، سنمرر عُمره أيضًا بالإضافة إلى اسمه:

sammy = Shark("Sammy", 5)

إذًا، تتيح البانيات تهيئة خاصيات الكائن لحظة إنشائه.

العمل مع عدة كائنات

تتيح لنا الأصناف إنشاء العديد من الكائنات المتماثلة التي تتبع نفس النمط. لتفهم ذلك بشكل أفضل، دعنا نضيف كائنًا آخر من الصنف ‎Shark‎ إلى برنامجنا:

class Shark:
    def __init__(self, name):
        self.name = name

    def swim(self):
        print(self.name + " is swimming.")

    def be_awesome(self):
        print(self.name + " is being awesome.")

def main():
    sammy = Shark("Sammy")
    sammy.be_awesome()
    stevie = Shark("Stevie")
    stevie.swim()

if __name__ == "__main__":
  main()

لقد أنشأنا كائنًا ثانيًا من الصنف ‎Shark‎ يسمى ‎stevie‎، ومرّرنا إليه الاسم ‎"Stevie"‎. في هذا المثال، استدعينا التابع ‎be_awesome()‎ مع الكائن ‎sammy‎، والتابع ‎swim()‎ مع الكائن ‎stevie‎.

لننفذ البرنامج:

python shark.py

سنحصل على المخرجات التالية:

Sammy is being awesome.
Stevie is swimming.

يبدو ظاهرًا في المخرجات أننا نستخدم كائنين مختلفين، الكائن ‎sammy‎ والكائن ‎stevie‎، وكلاهما من الصنف ‎Shark‎.

تتيح لنا الأصناف إنشاء عدة كائنات تتبع كلها نفس النمط دون الحاجة إلى بناء كل واحد منها من البداية.

خلاصة

تطرَّقنا في هذا الدرس إلى عِدَّة مفاهيم، مثل إنشاء الأصناف، وإنشاء الكائنات، وتهيئة الخاصيات باستخدام البانيات، والعمل مع أكثر من كائن من نفس الصنف.

تُعدُّ البرمجة الكائنية أحد المفاهيم الضرورية التي ينبغي أن يتعلمها كل مبرمجي بايثون، لأنها تساعد على كتابة شيفرات قابلة لإعادة الاستخدام، إذ أنَّ الكائنات التي تُنشَأ في برنامج ما يمكن استخدامها في برامج أخرى. كما أنّ البرامج الكائنية عادة ما تكون أوضح وأكثر مقروئية، خصوصًا في البرامج المعقدة التي تتطلب تخطيطًا دقيقًا، وهذا بدوره يسهل صيانة البرامج مستقبلًا.

هذه المقالة جزء من سلسة مقالات حول تعلم البرمجة في بايثون 3.

ترجمة -وبتصرّف- للمقال How To Construct Classes and Define Objects in Python 3 لصاحبته Lisa Tagliaferri

اقرأ أيضًا





تفاعل الأعضاء


لا توجد أيّة تعليقات بعد



يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن