دالة التهيئة المبدئية (__init__) وإدارة خصائص الكائنات


في هذا الدرس الاحترافي، سنتعمق في فهم دالة التهيئة المبدئية __init__ في بايثون، وكيف نستخدمها بفعالية لإدارة خصائص الكائنات وضمان تهيئتها بشكل صحيح عند الإنشاء.

سنتعلم كيفية بناء فئة بسيطة وإدارة بياناتها الأولية وتفاعلاتها.

1. أساسيات دالة __init__ والتهيئة الأولية

دالة __init__ هي دالة خاصة في بايثون تُعرف باسم "دالة التهيئة" أو "المُنشئ" (Constructor). تُستدعى هذه الدالة تلقائيًا في كل مرة يتم فيها إنشاء كائن جديد من الفئة. هدفها الرئيسي هو تهيئة الخصائص (Attributes) الأولية للكائن.

class Book:
    # تعريف الفئة (Class) 'كتاب'

    def __init__(self):
        # دالة التهيئة المبدئية (Constructor)
        # تُستدعى هذه الدالة تلقائيًا عند إنشاء كائن جديد من الفئة.
        # 'self' هو أول بارامتر ويشير إلى الكائن الحالي الذي يتم إنشاؤه.
        # هنا، نقوم بتهيئة خصائص افتراضية للكتاب.
        self.title = "عنوان غير معروف" # خاصية العنوان
        self.author = "مؤلف غير معروف" # خاصية المؤلف
        self.year = 0 # خاصية سنة النشر
        print("تم إنشاء كائن كتاب جديد.") # رسالة تأكيد الإنشاء

# إنشاء كائن (Object) من الفئة Book
book1 = Book()

# الوصول إلى خصائص الكائن وطباعتها
print(f"الكتاب الأول: {book1.title} للمؤلف {book1.author} في سنة {book1.year}")

ملاحظة تقنية: البارامتر self إلزامي في جميع دوال الفئة. إنه يمثل الكائن نفسه، مما يسمح لك بالوصول إلى خصائصه ودوائله الأخرى من داخل الفئة.

2. إدارة خصائص الكائنات وتمرير القيم

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

class Book:
    # تعريف الفئة (Class) 'كتاب'

    def __init__(self, title, author, year):
        # دالة التهيئة المبدئية التي تستقبل قيمًا للخصائص
        self.title = title   # تعيين العنوان من البارامتر
        self.author = author # تعيين المؤلف من البارامتر
        self.year = year     # تعيين سنة النشر من البارامتر
        print(f"تم إنشاء الكتاب '{self.title}'.")

    def get_info(self):
        # دالة لطباعة معلومات الكتاب بشكل منسق
        return f"الكتاب: '{self.title}'، المؤلف: {self.author}، سنة النشر: {self.year}"

# إنشاء كائنات بقيم محددة
book2 = Book("فن البرمجة", "دونالد كانوث", 1968)
book3 = Book("مقدمة في بايثون", "جويدو فان روسم", 1991)

# طباعة معلومات الكائنات باستخدام الدالة get_info
print(book2.get_info())
print(book3.get_info())

ملاحظة تقنية: عند تمرير البارامترات إلى __init__، فإنها تُعامل كمتغيرات محلية للدالة. يجب تعيينها إلى self.attribute_name لجعلها خصائص للكائن يمكن الوصول إليها من أي مكان خارج الدالة.

3. التفاعل مع الخصائص وتحديثها

بمجرد إنشاء الكائن وتعيين خصائصه، يمكننا الوصول إلى هذه الخصائص مباشرة أو تحديثها. من الممارسات الجيدة توفير دوال (Methods) داخل الفئة للتحكم في كيفية تعديل الخصائص، مما يضيف طبقة من التحقق من الصحة (Validation) إذا لزم الأمر.

class Book:
    # تعريف الفئة (Class) 'كتاب'

    def __init__(self, title, author, year):
        self.title = title
        self.author = author
        self.year = year
        print(f"تم إنشاء الكتاب '{self.title}'.")

    def get_info(self):
        return f"الكتاب: '{self.title}'، المؤلف: {self.author}، سنة النشر: {self.year}"

    def update_year(self, new_year):
        # دالة لتحديث سنة النشر مع بعض التحقق البسيط
        if new_year > self.year and new_year <= 2024: # افتراض أن 2024 هي السنة الحالية كحد أقصى
            self.year = new_year
            print(f"تم تحديث سنة نشر الكتاب '{self.title}' إلى {self.year}.")
        else:
            print(f"لا يمكن تحديث سنة النشر إلى {new_year}. يجب أن تكون أكبر من {self.year} ولا تتجاوز 2024.")

# إنشاء كائن
book4 = Book("تصميم البرمجيات النظيف", "روبرت مارتن", 2008)
print(f"قبل التحديث: {book4.get_info()}")

# تحديث سنة النشر
book4.update_year(2010)
print(f"بعد التحديث الأول: {book4.get_info()}")

# محاولة تحديث غير صالحة
book4.update_year(2005) # سنة أقدم
book4.update_year(2025) # سنة مستقبلية جدًا
print(f"بعد محاولات التحديث الفاشلة: {book4.get_info()}")

# الوصول المباشر للخاصية وتعديلها (ممكن ولكن قد يفتقر للتحقق)
book4.author = "روبرت س. مارتن" # تحديث مباشر للمؤلف
print(f"بعد التحديث المباشر للمؤلف: {book4.get_info()}")

ملاحظة تقنية: على الرغم من إمكانية الوصول إلى خصائص الكائن وتعديلها مباشرة (مثل book4.author = "...")، إلا أنه من الأفضل استخدام دوال (setters) لهذا الغرض، خاصةً إذا كنت بحاجة إلى تطبيق منطق عمل أو تحقق من صحة البيانات قبل التعديل.

الكود النهائي الكامل

إليك الكود الكامل الذي يجمع جميع المفاهيم التي تعلمناها:

class Book:
    """
    فئة لتمثيل كتاب، تحتوي على خصائص العنوان والمؤلف وسنة النشر.
    """

    def __init__(self, title, author, year):
        """
        دالة التهيئة المبدئية (Constructor) للكائن.
        تُستدعى عند إنشاء كائن جديد من الفئة Book.
        تأخذ العنوان والمؤلف وسنة النشر كبارامترات لتهيئة خصائص الكائن.
        """
        self.title = title   # تعيين خاصية العنوان
        self.author = author # تعيين خاصية المؤلف
        self.year = year     # تعيين خاصية سنة النشر
        print(f"تم إنشاء الكتاب '{self.title}' بنجاح.")

    def get_info(self):
        """
        دالة ترجع سلسلة نصية تحتوي على معلومات الكتاب بشكل منسق.
        """
        return f"الكتاب: '{self.title}'، المؤلف: {self.author}، سنة النشر: {self.year}"

    def update_year(self, new_year):
        """
        دالة لتحديث سنة نشر الكتاب.
        تتضمن تحققات بسيطة لضمان أن السنة الجديدة صالحة.
        """
        # التحقق من أن السنة الجديدة أكبر من السنة الحالية ولا تتجاوز 2024 (كمثال)
        if new_year > self.year and new_year <= 2024:
            self.year = new_year
            print(f"تم تحديث سنة نشر الكتاب '{self.title}' إلى {self.year}.")
        else:
            print(f"خطأ: لا يمكن تحديث سنة النشر إلى {new_year}. يجب أن تكون أكبر من {self.year} ولا تتجاوز 2024.")

    def __str__(self):
        """
        دالة خاصة تُستدعى عند محاولة تحويل الكائن إلى سلسلة نصية (مثل عند استخدام print()).
        توفر تمثيلاً نصيًا سهل القراءة للكائن.
        """
        return self.get_info()

# --- أمثلة على الاستخدام ---

# 1. إنشاء كائنات جديدة
book1 = Book("تعلم بايثون في 24 ساعة", "جون دو", 2020)
book2 = Book("هندسة البرمجيات", "ماري سميث", 2015)

print("\n--- معلومات الكتب الأولية ---")
print(book1) # تستخدم دالة __str__
print(book2)

# 2. الوصول إلى الخصائص وتعديلها
print(f"\nعنوان الكتاب الأول: {book1.title}")
book1.author = "جون أ. دو" # تحديث مباشر للخاصية
print(f"المؤلف الجديد للكتاب الأول: {book1.author}")

# 3. استخدام دالة التحديث
print("\n--- تحديث سنوات النشر ---")
book1.update_year(2022) # تحديث صالح
book2.update_year(2010) # تحديث غير صالح (أقدم)
book2.update_year(2026) # تحديث غير صالح (مستقبلي جداً)

print("\n--- معلومات الكتب بعد التحديثات ---")
print(book1)
print(book2)

النتيجة المتوقعة

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

تم إنشاء الكتاب 'تعلم بايثون في 24 ساعة' بنجاح.
تم إنشاء الكتاب 'هندسة البرمجيات' بنجاح.

--- معلومات الكتب الأولية ---
الكتاب: 'تعلم بايثون في 24 ساعة'، المؤلف: جون دو، سنة النشر: 2020
الكتاب: 'هندسة البرمجيات'، المؤلف: ماري سميث، سنة النشر: 2015

عنوان الكتاب الأول: تعلم بايثون في 24 ساعة
المؤلف الجديد للكتاب الأول: جون أ. دو

--- تحديث سنوات النشر ---
تم تحديث سنة نشر الكتاب 'تعلم بايثون في 24 ساعة' إلى 2022.
خطأ: لا يمكن تحديث سنة النشر إلى 2010. يجب أن تكون أكبر من 2015 ولا تتجاوز 2024.
خطأ: لا يمكن تحديث سنة النشر إلى 2026. يجب أن تكون أكبر من 2015 ولا تتجاوز 2024.

--- معلومات الكتب بعد التحديثات ---
الكتاب: 'تعلم بايثون في 24 ساعة'، المؤلف: جون أ. دو، سنة النشر: 2022
الكتاب: 'هندسة البرمجيات'، المؤلف: ماري سميث، سنة النشر: 2015