البرمجة الكائنية في بايثون - سلسلة بايثونات لتعلم لغة البايثون

البرمجة الكائنية في بايثون – سلسلة بايثونات لتعلم لغة البايثون

أهلا وسهلًا بكم في آخر مقال من سلسلة بايثونات لتعلم البايثون والذي نتناول فيه موضوع البرمجة الكائنية Object Oriented Programming والتي يختصرها جمع المبرمجون إلى OPP. البرمجة الكائنية في بايثون تُشبه لحد كبير البرمجة الكائنية في العديد من لغات البرمجة الأخرى ولكن مع وجود اختلافات.

قبل أن نتناول البرمجة الكائنية في بايثون ننصحك عزيزي القارئ بأخذ جولة في مقالات السلسلة السابقة.

مقالات السلسلة:

  1. لغة بايثون للمبتدئين – سلسلة بايثونات لتعلم البايثون والانطلاق في عالم البرمجة.
  2. النصوص في بايثون.
  3. المتغيرات والتراكيب في بايثون.
  4. جُمل التحكم في بايثون.
  5. الدوال والوحدات بايثون.
  6. معالجة الأخطاء في بايثون.
  7. البرمجة الكائنية في بايثون.

البرمجة الكائنية في بايثون

كل شيء في البايثون عبارة عن كائن object. الكائن عبارة عن نُسخة منشأة من فئة Class. تدعم البايثون مفاهيم البرمجة الكائنية الأربعة الأساسية والمُسماة OOP Pillars وهي التجريد Abstraction، وراثة الفئات class inheritance، التغليف encapsulation وتعدد الأشكال ploymorphisim.

تحتوي الفئة على خصائص ودوال يُمكن استخدامها من خلال الكائن أو من خلال كتابة اسم الفئة مباشرة ومن ثم اسم الخاصية. في المثال التالي نُعرف متغير نصي ونستخدم الدالة المُضمنة في بايثون dir في التعرف على الخصائص والدوال التي يُمكن استخدامها من خلال الفئة النصة str:

name = 'Pythonat'
print( dir(name) )

ستكون نتيجة الشيفرة السابقة قائمة تحتوي على كافة الخصائص والدوال الموجودة في تعريف الفئة str والتي هي نوع المتغير:

['__add__', '__class__', '__contains__', '__delattr__', '__dir__', 
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', 
'__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', 
'__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', 
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', 
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 
'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 
'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 
'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 
'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 
'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 
'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

كيف نُعَّرف فئة class في بايثون

لتعريف فئة في البايثون نستخدم الكلمة المحجوزة class ثم نتبعها باسم الفئة التي نُريدها ثم الأقواس العادية ( ) وبداخلها إسم الفئة التي ترث منها اذا أردنا ذلك:

class Blog(object):
    ....
    ....

object هنا هي الفئة الرئيسية في البايثون، ويتم الوراثة منها بشكل تلقائي عند تعريف أي فئة، لذلك يُعتبر كتابتها بالطريقة السابقة أمرًا اختياريًا في بايثون 3.

تعريف خصائص ومتغيرات الفئة

 يتضمن تعريف الفئة في بايثون تعريف الخصائص والمتغيرات والدوال بداخلها. عند تعريف دالة نُمرر لها أولًا المؤشر الخاص بالكائن الذي يتم انشاؤه من هذه الفئة وعادةً ما يكون باسم self ثم المعاملات إن وجدت.

الدالة البانية في تعريف الفئة في البايثون هي __init__ ويتم كتابة المعاملات التي ستمثل الخصائص بين قوسي الدالة البانية. يتم استدعاء الدالة البانية كل مرة عند إنشاء كائن من الفئة. الدالة __init__ هي المقابل لمصطلح constructor في لغات البرمجة الأخرى.

class ClassName():
    def __init__(self, attrib1, attrib2, attrib3,...):
		...
	
	...

المثال التالي يُوضح كيفية تعريف فئة بإسم Blog تتضمن الخصائص التالية:

  • blogName
  • blogUrl
  • isActive

بالإضافة إلى دالة باسم blogInfo و __del__. الأولى تُرجع معلومات ما عن الكائن المُنشأ من هذه الفئة والثانية تعمل على تطبيق دالة حذف الكائن والتي سيتم تنفيذها عند استخدام دالة del على الكائن:

class Blog():
    blogsCounter = 0
    def __init__(self, blogName, blogUrl, isActive):
        self.blogName = blogName
        self.blogUrl = blogUrl
        self.isActive = isActive
        Blog.blogsCounter += 1

    def blogInfo(self):
        print('Blog name is: ', self.blogName)
        print('Blog url is: ', self.blogUrl)
        print('Is the blog active? ', self.isActive)

    def __del__(self):
        print('Deleted object.')
        Blog.blogsCounter -= 1

def main():
    print(Blog.blogsCounter)
    b1 = Blog('Pythonat', 'https://pythonat.com', True)

    print(Blog.blogsCounter)

    b1.blogInfo()

    del(b1)
    print(Blog.blogsCounter)

if __name__ == '__main__':
    main()

في بداية تعريف الفئة عرفنا متغير باسم blogsCounter سيُمثل العدد الحالي من العناصر التي تم انشاؤها باستخدام فئة Blog.

الدالة البانية __init__ لها ثلاث معاملات هي الخصائص التي ذكرناها في الأعلى. هذا يعني أننا عند انشاء كائن من هذه الفئة لابد من تمرير 3 معطيات للدالة البانية.

اضافة توثيق للفئة في بايثون

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

لإضافة توثيق الفئة العام نكتب النص التوثيقي بين ثلاثة محرفات من نوع التنصيص المزدوج كالتالي:

class className():
    """ Documentation string """
    ...
    ...

بنفس الطريقة، لإضافة توثيق خاص بدالة ما داخل الفئة نكتب التوثيق بعد سطر تعريف الدالة الأول. عدلنا المثال الأول الخاص بتعريف فئة Blog ليُصبح محتويًا على توثيق كما يلي:

class Blog:
    """ This class is used to define Blog site info """
    blogsCounter = 0
    def __init__(self, blogName, blogUrl, isActive):
        self.blogName = blogName
        self.blogUrl = blogUrl
        self.isActive = isActive
        Blog.blogsCounter += 1

    def blogInfo(self):
        """ Return general info about the blog """
        print('Blog name is: ', self.blogName)
        print('Blog url is: ', self.blogUrl)
        print('Is the blog active? ', self.isActive)

    def __del__(self):
        """ Called when deleting object from this class """
        print('Deleted object.')
        Blog.blogsCounter -= 1

def main():
    print(Blog.blogsCounter)
    b1 = Blog('Pythonat', 'https://pythonat.com', True)

    print(help(Blog))

    print(Blog.blogsCounter)

    b1.blogInfo()

    del(b1)
    print(Blog.blogsCounter)



if __name__ == '__main__':
    main()

سيكون ناتج استخدام دالة help لفئة Blog بالشكل التالي:

add doc to class definition - python

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

نتمنى أن نكون وُفقنا في بايثونات في إيصال المعلومة بالشكل الصحيح حول الموضوع ونسعد بأي ملاحظة في التعليقات. كما نتمنى منكم مشاركة مقالات بايثونات في منصات التواصل الاجتماعي مثل تويتر وفيسبوك حتى تعم الفائدة.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *