جاري تحميل المحتوى...
تعلمت حتى الآن تنظيم البرنامج باستخدام Variables وFunctions وCollections وModules. توجد طريقة أخرى تساعدنا عندما نريد تمثيل شيء له بيانات مرتبطة به وسلوك يعمل على تلك البيانات. هنا تأتي مقدمة Object-Oriented Programming أو OOP.
في هذا الفصل سنركز على الأساسيات فقط: Class وObject وInstance و__init__ وself وInstance Attributes وMethods. لن ندخل في موضوعات OOP المتقدمة.
لنفترض أن برنامجًا يتعامل مع طلاب. كل طالب قد يمتلك اسمًا ودرجة، وقد نحتاج أيضًا إلى عمليات مرتبطة به مثل إضافة نقاط أو عرض معلوماته.
يمكننا استخدام Variables وFunctions منفصلة، لكن مع زيادة البيانات قد يكون من المفيد جمع البيانات المرتبطة بالشيء والسلوك الذي يعمل عليها داخل تنظيم واحد واضح.
البرمجة الكائنية تقدم طريقة لتحقيق ذلك باستخدام Objects.
Object-Oriented Programming أسلوب لتنظيم البرنامج باستخدام Objects تجمع بيانات مرتبطة بها وسلوكًا يعمل على تلك البيانات.
هذا لا يعني أن OOP هي الطريقة الوحيدة أو الأفضل دائمًا لكتابة برامج Python. هي أسلوب مفيد نتعلم أساسياته حتى نفهم Classes وObjects التي سنقابلها في كثير من الأكواد والمكتبات والمشاريع.
يمكن اعتبار Class تعريفًا أو قالبًا يحدد البيانات والسلوك الذي يمكن أن تمتلكه Objects من هذا النوع.
أبسط مثال:
class Student:
pass
هنا Student هو اسم Class.
الكلمة class تستخدم لتعريف Class جديدة.
بعد تعريف Class يمكن إنشاء Object منها.
class Student:
pass
student1 = Student()
في هذا المثال:
Student هي Class.student1 تحمل Object أُنشئت من Student.في المستوى الحالي يمكن استخدام مصطلحي Object وInstance للدلالة على الكائن الذي أُنشئ من Class.
| المفهوم | المعنى المبسط | مثال |
|---|---|---|
Class |
التعريف أو القالب. | Student |
Object / Instance |
كائن فعلي أُنشئ من Class. | student1 |
يمكن استخدام Method خاصة باسم __init__ لتهيئة بيانات Instance.
class Student:
def __init__(self, name):
self.name = name
ثم ننشئ Object:
student1 = Student("Ali")
أصبحت student1 تحمل Instance لديها Attribute باسم name وقيمتها "Ali".
__init__؟__init__ هي Method خاصة تستدعى تلقائيًا ضمن عملية إنشاء Instance، وتستخدم عادة لتهيئة بياناتها الأولية.
في المثال:
class Student:
def __init__(self, name):
self.name = name
عند كتابة:
student1 = Student("Ali")
تستخدم القيمة "Ali" لتهيئة Attribute داخل Instance.
نقول إن __init__ تهيئ بيانات Instance، ولا نصفها بأنها التي تنشئ Object تقنيًا. لن ندخل في تفاصيل إنشاء Objects الداخلية في هذا الفصل.
self؟self تشير بصورة مبسطة إلى Instance الحالية التي تعمل عليها Method.
class Student:
def __init__(self, name):
self.name = name
في self.name نحفظ Attribute داخل Object الحالية.
self ليست Python keyword محجوزة. هي الاسم المتعارف عليه للParameter الذي يمثل Instance الحالية، ونستخدم هذا الاسم وفق الأسلوب القياسي في Python.
هذه من أهم النقاط للمبتدئ.
def __init__(self, name):
self.name = name
في السطر:
self.name = name
name على اليمين Parameter استقبل القيمة المرسلة عند إنشاء Instance.self.name على اليسار Instance Attribute نحفظ فيها القيمة داخل Object الحالية.إذا أنشأنا:
student1 = Student("Ali")
فالقيمة "Ali" تصل إلى Parameter باسم name، ثم تحفظ في student1.name.
سنركز في هذا الفصل على Instance Attributes فقط.
class Student:
def __init__(self, name, grade):
self.name = name
self.grade = grade
ثم:
student1 = Student("Ali", 90)
print(student1.name)
print(student1.grade)
الناتج:
Ali
90
القيمتان name وgrade محفوظتان هنا داخل student1.
نستخدم النمط:
object.attribute
مثل:
print(student1.name)
print(student1.grade)
لا نحتاج في هذه المقدمة إلى أدوات متقدمة للوصول إلى Attributes.
يمكن في المثال البسيط تغيير قيمة Instance Attribute مباشرة:
student1.grade = 95
print(student1.grade)
الناتج:
95
هذا التغيير يخص Attribute الموجودة داخل student1.
Method هي Function معرفة داخل Class، وتعمل عادة على بيانات Object.
class Student:
def __init__(self, name):
self.name = name
def greet(self):
return f"مرحبًا، أنا {self.name}"
Method باسم greet() تستخدم self.name من Instance الحالية.
بعد إنشاء Object:
student1 = Student("Ali")
يمكن استدعاء Method هكذا:
print(student1.greet())
الناتج:
مرحبًا، أنا Ali
في الاستدعاء المعتاد لا نمرر self يدويًا. نكتب student1.greet().
يمكن لـMethod قراءة Attributes الخاصة بالObject:
class Student:
def __init__(self, name, grade):
self.name = name
self.grade = grade
def info(self):
return f"{self.name}: {self.grade}"
عند استدعاء info() تستخدم Method القيم المخزنة داخل Instance الحالية.
يمكن لـMethod أيضًا تعديل بيانات Object.
class Counter:
def __init__(self, value):
self.value = value
def increase(self):
self.value += 1
ثم:
counter = Counter(5)
counter.increase()
print(counter.value)
الناتج:
6
Method increase() عدلت self.value داخل Object الحالية.
يمكن أن تحتوي Method على Parameters إضافية بعد self.
class Student:
def __init__(self, grade):
self.grade = grade
def add_points(self, points):
self.grade += points
ثم:
student = Student(80)
student.add_points(5)
print(student.grade)
الناتج:
85
هنا:
self تمثل Instance الحالية.points Parameter إضافي نستقبل من خلاله القيمة 5.يمكن إنشاء عدة Objects من Class نفسها:
class Student:
def __init__(self, name, grade):
self.name = name
self.grade = grade
student1 = Student("Ali", 90)
student2 = Student("Sara", 95)
student1 وstudent2 Objects مختلفتان من Class نفسها.
في المثال السابق، لكل Object قيم Instance Attributes الخاصة بها.
student1.grade = 80
print(student1.grade)
print(student2.grade)
الناتج:
80
95
تغيير student1.grade لم يغير student2.grade.
هذا لأننا نتعامل هنا مع Instance Attributes مستقلة لكل Object.
لننشئ Class بسيطة لتمثيل Product لها اسم وسعر، مع Method لتطبيق خصم وأخرى لعرض المعلومات.
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
def apply_discount(self, amount):
self.price -= amount
def info(self):
return f"{self.name}: {self.price}"
ثم:
product = Product("Book", 100)
product.apply_discount(20)
print(product.info())
الناتج:
Book: 80
في هذا المثال جمعت Class البيانات:
namepriceمع السلوك:
apply_discount()info()وهذه هي الفكرة الأساسية التي نريد فهمها في هذا الفصل: تنظيم بيانات مرتبطة وسلوك يعمل عليها.
تكتب أسماء Classes عادة بأسلوب PascalCase.
أمثلة:
StudentProductBankAccountهذه ملاحظة تنظيمية قصيرة وليست محورًا رئيسيًا في الفصل.
self داخل Instance Methodعند تعريف Instance Method نستخدم self لتمثيل Object الحالية.
def greet(self):
return self.name
name = name بدل حفظ القيمة داخل Objectإذا كان هدفنا إنشاء Instance Attribute نكتب:
self.name = name
أما:
name = name
فلا تنشئ self.name داخل Instance.
Student هي Class، بينما student1 يمكن أن تكون Object أُنشئت منها.
إذا كانت name أنشئت في أمثلتنا كـInstance Attribute باستخدام self.name، فنصل إليها من Object مثل:
student1.name
ولا نفترض في هذه الأمثلة أن Student.name تمثل القيمة الخاصة بـstudent1.
عند الرغبة في إنشاء Object نستخدم استدعاء Class، مثل:
student1 = Student("Ali")
أما كتابة اسم Class وحده فلا تنشئ لنا Instance جديدة محفوظة في المتغير بهذه الصورة.
self يدويًا عند الاستدعاء المعتادإذا كانت Method:
def greet(self):
return self.name
فالاستدعاء المعتاد هو:
student1.greet()
وليس من المطلوب تمرير student1 مرة أخرى مكان self.
في أمثلة Instance Attributes الحالية، تغيير student1.grade لا يغير student2.grade تلقائيًا.
أنشئ Class باسم Book دون بيانات، ثم أنشئ Object منها باسم book1.
أنشئ Class باسم Student تحتوي __init__ تستقبل name وتحفظها في self.name.
أضف Attribute باسم grade إلى المثال السابق، ثم اطبع قيمتها باستخدام student.grade.
غيّر student.grade إلى قيمة جديدة ثم اطبعها.
أضف Method باسم greet() تعيد نصًا يستخدم self.name.
أنشئ Method باسم add_points() تستقبل Parameter إضافيًا وتزيد self.grade.
أنشئ Objectين من Student بقيم مختلفة، ثم غيّر Attribute في Object الأولى وتحقق أن قيمة الثانية لم تتغير.
أنشئ Class بسيطة باسم Product تجمع اسمًا وسعرًا وMethod تعدل السعر.
OOP أسلوب لتنظيم البيانات والسلوك باستخدام Objects.Class هي التعريف أو القالب.Object أو Instance كائن أُنشئ من Class.class لتعريف Class.__init__ تستخدم لتهيئة بيانات Instance ضمن عملية إنشائها.self تمثل Instance الحالية داخل Instance Method بصورة مبسطة.self ليست Python keyword محجوزة؛ هي الاسم المتعارف عليه لهذا Parameter.self.name = name تكون name Parameter وself.name Instance Attribute.object.attribute.student.grade = 95.student.greet() دون تمرير self يدويًا.self.في الفصل التالي ستجمع مفاهيم Python التي تعلمتها في تطبيق تكاملي صغير ومنظم. لن نبدأ هذا التطبيق هنا، كما أن استخدام OOP فيه ليس شرطًا أساسيًا.
نشر في ١٢ أغسطس ٢٠٢٦