5. الفئات والكائنات
الفئة هي القالب الذي تُصنع منه الكائنات. ويُقال إن الكائن هو مثيل لفئة ما.
![]() |
5.1. فئة «Objet»
برنامج (classes_01)
# -*- coding=utf-8 -*-
class Objet:
"""une classe Objet vide"""
# يمكن أن يكون لأي متغير سمات بحكم بنيته
obj1=Objet()
obj1.attr1="un"
obj1.attr2=100
# يعرض الكائن
print "objet1=[{0},{1}]".format(obj1.attr1,obj1.attr2)
# يُعدّل الكائن
obj1.attr2+=100
# يعرض الكائن
print "objet1=[{0},{1}]".format(obj1.attr1,obj1.attr2)
# يعين المرجع «objet1» إلى «objet2»
obj2=obj1
# يعدل الكائن 2
obj2.attr2=0
# يعرض الكائنين
print "objet1=[{0},{1}]".format(obj1.attr1,obj1.attr2)
print "objet2=[{0},{1}]".format(obj2.attr1,obj2.attr2)
ملاحظات:
- السطر 4: شكل آخر من أشكال التعليقات. هذا التعليق، الذي يسبقه ثلاثة "، يمكن أن يمتد على عدة أسطر؛
- السطران 3 و4: فئة كائن فارغة؛
- السطر 7: إنشاء مثيل لفئة Objet؛
- السطر 17: نسخ المراجع. المتغيران obj1 و obj2 هما مؤشران (مراجع) إلى نفس الكائن.
النتائج
5.2. فئة «Personne»
برنامج (classes_02)
# -*- coding=utf-8 -*-
class Personne:
# سمات الفئة
# غير مُعلنة - يمكن إنشاؤها ديناميكيًا
# طريقة
def identite(self):
# في البداية، تستخدم سمات غير موجودة
return "[{0},{1},{2}]".format(self.prenom,self.nom,self.age)
# ---------------------------------- main
# السمات عامة ويمكن إنشاؤها ديناميكيًا
p=Personne()
p.prenom="Paul"
p.nom="Langevin"
p.age=48
# استدعاء دالة
print "personne={0}\n".format(p.identite())
ملاحظات:
- الأسطر 3-10: فئة تحتوي على طريقة واحدة؛
- السطر 8: يجب أن يكون المعلمة الأولى لأي دالة في الفئة هي الكائن self الذي يشير إلى الكائن الحالي.
النتائج
5.3. فئة Personne مع منشئ
البرنامج (classes_03)
# -*- coding=utf-8 -*-
class Personne:
# منشئ
def __init__(self,prenom,nom,age):
self.prenom=prenom;
self.nom=nom;
self.age=age;
# طريقة
def identite(self):
# في البداية، تستخدم سمات غير موجودة
return "[{0},{1},{2}]".format(self.prenom,self.nom,self.age)
# ---------------------------------- main
# كائن Personne
p=Personne("Paul","Langevin",48)
# استدعاء طريقة
print "personne={0}\n".format(p.identite())
ملاحظات:
- السطر 6: يُسمى مُنشئ الفئة __init__. وكما هو الحال مع الطرق الأخرى، فإن المعلمة الأولى له هي self؛
- السطر 18: يتم إنشاء كائن Personne باستخدام منشئ الفئة.
النتائج
5.4. فئة Personne مع عناصر التحقق من الصحة في المنشئ
البرنامج (classes_04)
# -*- coding=utf-8 -*-
import re
# -------------------
# فئة استثناء خاصة
class MyError(Exception):
pass
class Personne:
# منشئ
def __init__(self,prenom="x",nom="x",age=0):
# يجب ألا يكون الاسم الأول فارغًا
match=re.match(r"^\s*(\S+)\s*$",prenom)
if not match:
raise MyError("Le prenom ne peut etre vide")
else:
self.prenom=match.groups()[0]
# يجب ألا يكون الاسم فارغًا
match=re.match(r"^\s*(\S+)\s*$",nom)
if not match:
raise MyError("Le nom ne peut etre vide")
else:
self.nom=match.groups()[0]
# يجب أن يكون العمر صالحًا
match=re.match(r"^\s*(\d+)\s*$",str(age))
if not match:
raise MyError("l'age doit etre un entier positif")
else:
self.age=match.groups()[0]
def __str__(self):
return "[{0},{1},{2}]".format(self.prenom,self.nom,self.age)
# ---------------------------------- اليد
# كائن «شخص»
try:
p=Personne(" Paul "," Langevin ",48)
print "personne={0}".format(p)
except MyError, erreur:
print erreur
# كائن «شخص» آخر
try:
p=Personne(" xx "," yy "," zz")
print "personne={0}".format(p)
except MyError, erreur:
print erreur
# شخص آخر
try:
p=Personne()
print "personne={0}".format(p)
except MyError, erreur:
print erreur
ملاحظات:
- السطران 7-8: فئة MyError مشتقة من الفئة Exception. وهي لا تضيف أي وظائف إلى هذه الأخيرة. إن وجودها يقتصر على توفير استثناء خاص بها؛
- السطر 13: يحتوي المنشئ على قيم افتراضية لمعلماته. وبالتالي، فإن العملية p=Personne() تعادل p=Personne("x","x",0)؛
- الأسطر 15-9: يتم تحليل المعلمة prenom. يجب ألا تكون فارغة. إذا لم يكن الأمر كذلك، يتم إثارة الاستثناء MyError مع رسالة خطأ؛
- الأسطر 21-25: الأمر نفسه بالنسبة للاسم؛
- الأسطر 27-31: التحقق من العمر؛
- السطران 33-34: تحل الدالة __str__ محل الطريقة التي كانت تُسمى سابقًا identite؛
- الأسطر 38-42: إنشاء مثيل لشخص ثم عرض هويته؛
- السطر 39: إنشاء مثيل؛
- السطر 40: العرض. تطلب العملية عرض الشخص p في شكل سلسلة أحرف. ثم يقوم مترجم Python تلقائيًا باستدعاء الطريقة p.__str__() إن وجدت. تؤدي هذه الطريقة نفس دور الطريقة toString() في لغة Java أو في لغات .NET؛
- السطور 41-42: معالجة أي استثناء محتمل من النوع MyError. ثم يعرض رسالة الخطأ المرتبطة بالاستثناء؛
- الأسطر 44-48: الأمر نفسه بالنسبة لشخص ثانٍ تم إنشاء مثيل له باستخدام معلمات خاطئة؛
- الأسطر 50-54: الأمر نفسه بالنسبة لشخص ثالث تم إنشاء مثيل له باستخدام المعلمات الافتراضية.
النتائج
5.5. إضافة طريقة تعمل كمنشئ ثانٍ
البرنامج (classes_05)
# -*- coding=utf-8 -*-
import re
# -------------------
# فئة استثناء مالكة
class MyError(Exception):
pass
class Personne:
# سمات الفئة
# غير مُعلنة - يمكن إنشاؤها ديناميكيًا
# منشئ
def __init__(self,prenom="x",nom="x",age=0):
# يجب ألا يكون حقل الاسم فارغًا
match=re.match(r"^\s*(\S+)\s*$",prenom)
if not match:
raise MyError("Le prenom ne peut etre vide")
else:
self.prenom=match.groups()[0]
# يجب ألا يكون اسم العائلة فارغًا
match=re.match(r"^\s*(\S+)\s*$",nom)
if not match:
raise MyError("Le nom ne peut etre vide")
else:
self.nom=match.groups()[0]
# يجب أن يكون العمر صالحًا
match=re.match(r"^\s*(\d+)\s*$",str(age))
if not match:
raise MyError("l'age doit etre un entier positif")
else:
self.age=match.groups()[0]
def initWithPersonne(self,p):
# تقوم بتهيئة الكائن الحالي بشخص p
self.__init__(p.prenom,p.nom,p.age)
def __str__(self):
return "[{0},{1},{2}]".format(self.prenom,self.nom,self.age)
# ---------------------------------- main
# كائن «شخص»
try:
p0=Personne(" Paul "," Langevin ",48)
print "personne={0}".format(p0)
except MyError, erreur:
print erreur
# كائن «شخص» آخر
try:
p1=Personne(" xx "," yy "," zz")
print "personne={0}".format(p1)
except MyError, erreur:
print erreur
# شخص آخر
p2=Personne()
try:
p2.initWithPersonne(p0)
print "personne={0}".format(p2)
except MyError, erreur:
print erreur
ملاحظات:
- يكمن الاختلاف عن البرنامج النصي السابق في الأسطر 35-37. تمت إضافة الطريقة initWithPersonne. وتستدعي هذه الطريقة المنشئ __init__. لا توجد إمكانية، كما هو الحال في اللغات المحددة الأنواع، لوجود طرق تحمل الاسم نفسه وتتميز بطبيعة معلماتها أو نتائجها. وبالتالي، لا توجد إمكانية لوجود عدة منشئات تقوم بإنشاء الكائن بناءً على معلمات مختلفة، وهنا كائن من النوع Personne.
النتائج
5.6. قائمة بكائنات Personne
برنامج (classes_06)
# -*- coding=utf-8 -*-
class Personne:
...
# ---------------------------------- main
# إنشاء قائمة بكائنات «شخص»
groupe=[Personne("Paul","Langevin",48), Personne("Sylvie","Lefur",70)]
# هوية هؤلاء الأشخاص
for i in range(len(groupe)):
print "groupe[{0}]={1}".format(i,groupe[i])
ملاحظات:
- الأسطر 3-5: الفئة Personne التي سبق وصفها
النتائج
5.7. إنشاء فئة مشتقة من فئة Personne
البرنامج (classes_07)
# -*- coding=utf-8 -*-
import re
class Personne:
...
class Enseignant(Personne):
def __init__(self,prenom="x",nom="x",age=0,discipline="x"):
Personne.__init__(self,prenom,nom,age)
self.discipline=discipline
def __str__(self):
return "[{0},{1},{2},{3}]".format(self.prenom,self.nom,self.age,self.discipline)
# ---------------------------------- يد
# إنشاء قائمة بكائنات «شخص» ومشتقاتها
groupe=[Enseignant("Paul","Langevin",48,"anglais"), Personne("Sylvie","Lefur",70)]
# هوية هؤلاء الأشخاص
for i in range(len(groupe)):
print "groupe[{0}]={1}".format(i,groupe[i])
ملاحظات:
- السطران 5-6: الفئة Personne المحددة مسبقًا؛
- السطر 8: يُعلن الفئة Enseignant باعتبارها فئة مشتقة من فئة Personne؛
- السطر 10: يجب أن يستدعي منشئ الفئة المشتقة Enseignant منشئ الفئة الأم Personne؛
- السطران 21-22: لعرض «groupe[i]»، يستخدم المُفسر الطريقة «groupe[i].__str__()». الطريقة __str__() المستخدمة هي طريقة الفئة الفعلية لـ groupe[i] كما توضح النتائج أدناه.
النتائج
5.8. إنشاء فئة ثانية مشتقة من فئة «Personne»
البرنامج (classes_08)
# -*- coding=utf-8 -*-
import re
class Personne:
...
class Enseignant(Personne):
...
class Etudiant(Personne):
def __init__(self,prenom="x",nom="x",age=0,formation="x"):
Personne.__init__(self,prenom,nom,age)
self.formation=formation
def __str__(self):
return "[{0},{1},{2},{3}]".format(self.prenom,self.nom,self.age,self.formation)
# ---------------------------------- الرئيسية
# إنشاء قائمة بكائنات «شخص» ومشتقاتها
groupe=[Enseignant("Paul","Langevin",48,"anglais"), Personne("Sylvie","Lefur",70), Etudiant("Steve","Boer",22,"iup2 qualite")]
# هوية هؤلاء الأشخاص
for i in range(len(groupe)):
print "groupe[{0}]={1}".format(i,groupe[i])
ملاحظات:
- هذا البرنامج النصي مشابه للبرنامج النصي السابق.
النتائج
