Skip to content

5. الفئات والكائنات

الفئة هي القالب الذي يتم من خلاله إنشاء الكائنات. ويُقال إن الكائن هو مثيل لفئة ما.

  

5.1. فئة كائن


برنامج (classes_01)

#   -*- coding=utf-8 -*-

class Objet:
    """une classe Objet vide"""

#   any variable can have attributes by construction
obj1=Objet()
obj1.attr1="un"
obj1.attr2=100
#  displays the
print "objet1=[{0},{1}]".format(obj1.attr1,obj1.attr2)
#   modify object
obj1.attr2+=100
#  displays the
print "objet1=[{0},{1}]".format(obj1.attr1,obj1.attr2)
#   assigns object1 reference to object2
obj2=obj1
#   modify obj2
obj2.attr2=0
#   displays both objects
print "objet1=[{0},{1}]".format(obj1.attr1,obj1.attr2)
print "objet2=[{0},{1}]".format(obj2.attr1,obj2.attr2)

ملاحظات:

  • السطر 4: شكل آخر من أشكال التعليقات. يسبقه ثلاثة ""، ويمكن أن يمتد على عدة أسطر؛
  • السطران 3-4: فئة كائن فارغة؛
  • السطر 7: إنشاء مثيل لفئة Object؛
  • السطر 17: نسخ مرجعي. المتغيران obj1 و obj2 هما مؤشران (مرجعان) إلى نفس الكائن.

النتائج

1
2
3
4
objet1=[un,100]
objet1=[un,200]
objet1=[un,0]
objet2=[un,0]

5.2. فئة Person


البرنامج (classes_02)

#    -*- coding=utf-8 -*-

class Personne:
    #    class attributes
    #    undeclared - can be created dynamically

    #    method
    def identite(self):
        #    a priori, uses non-existent attributes
        return "[{0},{1},{2}]".format(self.prenom,self.nom,self.age)

#    ---------------------------------- main
#  attributes are public and can be created dynamically
p=Personne()
p.prenom="Paul"
p.nom="Langevin"
p.age=48
#    method call
print "personne={0}\n".format(p.identite())

ملاحظات:

  • الأسطر 3-10: فئة تحتوي على طريقة؛
  • السطر 8: يجب أن تحتوي كل دالة في الفئة على الكائن self — الذي يشير إلى الكائن الحالي — كمعلمة أولى لها.

النتائج

personne=[Paul,Langevin,48]

5.3. فئة Person مع منشئ


البرنامج (classes_03)

#   -*- coding=utf-8 -*-

class Personne:

    #   manufacturer
    def __init__(self,prenom,nom,age):
        self.prenom=prenom;
        self.nom=nom;
        self.age=age;

    #   method
    def identite(self):
        #   a priori, uses non-existent attributes
        return "[{0},{1},{2}]".format(self.prenom,self.nom,self.age)

#   ---------------------------------- main
#   a Person object
p=Personne("Paul","Langevin",48)
#   method call
print "personne={0}\n".format(p.identite())

ملاحظات:

  • السطر 6: يُسمى منشئ الفئة __init__. وكما هو الحال مع الطرق الأخرى، فإن المعلمة الأولى له هي self؛
  • السطر 18: يتم إنشاء كائن Person باستخدام منشئ الفئة.

النتائج

personne=[Paul,Langevin,48]

5.4. فئة Person مع فحوصات الصحة في المنشئ


البرنامج (classes_04)

#    -*- coding=utf-8 -*-

import re

# -------------------
#    a proprietary exception class
class MyError(Exception):
    pass

class Personne:

    #    manufacturer
    def __init__(self,prenom="x",nom="x",age=0):
         #  first name must be non-empty
        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]
        #  name must be non-empty
        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]
        #  age must be valid
        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)

#    ---------------------------------- main
#    a Person object
try:
    p=Personne("  Paul  ","  Langevin  ",48)
    print "personne={0}".format(p)
except MyError, erreur:
    print erreur
#    another object Nobody
try:
    p=Personne("  xx  ","  yy  ","  zz")
    print "personne={0}".format(p)
except MyError, erreur:
    print erreur
#    another person
try:
    p=Personne()
    print "personne={0}".format(p)
except MyError, erreur:
    print erreur

ملاحظات:

  • السطران 7-8: فئة MyError مشتقة من فئة Exception. وهي لا تضيف أي وظائف إلى الأخيرة. إنها موجودة فقط لتوفير استثناء مخصص؛
  • السطر 13: يحتوي المنشئ على قيم افتراضية لمعلماته. وبالتالي، فإن العملية p = Person() تعادل p = Person("x", "x", 0)؛
  • الأسطر 15–9: يتم فحص المعلمة first_name. يجب ألا تكون فارغة. إذا كانت فارغة، يتم إلقاء استثناء MyError مع رسالة خطأ؛
  • الأسطر 21–25: الأمر نفسه بالنسبة لـ last_name؛
  • الأسطر 27–31: التحقق من العمر؛
  • السطور 33-34: تحل الدالة __str__ محل الطريقة التي كانت تسمى سابقًا identite؛
  • الأسطر 38–42: إنشاء مثيل لـ Person وعرض هويته؛
  • السطر 39: إنشاء مثيل؛
  • السطر 40: العرض. تتطلب العملية عرض الشخص p كسلسلة. ثم يقوم مترجم Python تلقائيًا باستدعاء الطريقة p.__str__() إذا كانت موجودة. تخدم هذه الطريقة نفس الغرض الذي تخدمه الطريقة toString() في لغات Java أو .NET؛
  • الأسطر 41–42: معالجة استثناء MyError المحتمل. ثم عرض رسالة الخطأ المرتبطة بالاستثناء؛
  • الأسطر 44-48: نفس ما سبق بالنسبة لمثيل ثانٍ من Person تم إنشاؤه بمعلمات غير صحيحة؛
  • الأسطر 50–54: نفس ما سبق بالنسبة لمثيل ثالث من Person تم إنشاؤه باستخدام المعلمات الافتراضية.

النتائج

1
2
3
personne=[Paul,Langevin,48]
l'age doit etre un entier positif
personne=[x,x,0]

5.5. إضافة طريقة تعمل كمنشئ ثانٍ


البرنامج (classes_05)

#    -*- coding=utf-8 -*-

import re

# -------------------
#    a proprietary exception class
class MyError(Exception):
    pass

class Personne:
    #    class attributes
    #    undeclared - can be created dynamically

    #    manufacturer
    def __init__(self,prenom="x",nom="x",age=0):
         #  first name must be non-empty
        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]
        #  name must be non-empty
        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]
            #  age must be valid
        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):
        #  initializes the current object with a person p
        self.__init__(p.prenom,p.nom,p.age)

    def __str__(self):
        return "[{0},{1},{2}]".format(self.prenom,self.nom,self.age)

#    ---------------------------------- main
#    a Person object
try:
    p0=Personne("  Paul  ","  Langevin  ",48)
    print "personne={0}".format(p0)
except MyError, erreur:
    print erreur
#    another object Nobody
try:
    p1=Personne("  xx  ","  yy  ","  zz")
    print "personne={0}".format(p1)
except MyError, erreur:
    print erreur
#    another person
p2=Personne()
try:
    p2.initWithPersonne(p0)
    print "personne={0}".format(p2)
except MyError, erreur:
    print erreur

ملاحظات:

  • يكمن الاختلاف عن البرنامج النصي السابق في الأسطر 35-37. فقد أضفنا الطريقة initWithPerson. وتقوم هذه الطريقة باستدعاء مُنشئ __init__. وعلى عكس اللغات المُصنَّفة، لا يمكن وجود طرق تحمل الاسم نفسه ويتم تمييزها بناءً على طبيعة معلماتها أو قيمها المرجعة. ولذلك، لا يمكن وجود مُنشِئات متعددة تُنشئ الكائن من معلمات مختلفة، وفي هذه الحالة كائن من النوع Person.

النتائج

1
2
3
personne=[Paul,Langevin,48]
l'age doit etre un entier positif
personne=[Paul,Langevin,48]

5.6. قائمة بكائنات Person


البرنامج (classes_06)

#   -*- coding=utf-8 -*-

class Personne:
    ...

#   ---------------------------------- main
#   create a list of person objects
groupe=[Personne("Paul","Langevin",48), Personne("Sylvie","Lefur",70)]
#  identity of these persons
for i in range(len(groupe)):
  print "groupe[{0}]={1}".format(i,groupe[i])

ملاحظات:

  • الأسطر 3-5: فئة Person التي سبق وصفها

النتائج

groupe[0]=[Paul,Langevin,48]
groupe[1]=[Sylvie,Lefur,70]

5.7. إنشاء فئة مشتقة من فئة Person


البرنامج (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)


#    ---------------------------------- main
#  create a list of Personne objects and derivatives
groupe=[Enseignant("Paul","Langevin",48,"anglais"), Personne("Sylvie","Lefur",70)]
#  identity of these persons
for i in range(len(groupe)):
  print "groupe[{0}]={1}".format(i,groupe[i])

ملاحظات:

  • السطران 5-6: تم تعريف فئة Person بالفعل؛
  • السطر 8: يُعلن فئة Teacher كفئة فرعية لفئة Person؛
  • السطر 10: يجب أن يستدعي منشئ فئة Teacher المشتقة منشئ فئة Person الأصلية؛
  • السطران 21-22: لعرض group[i]، يستخدم المترجم الطريقة group[i].__str__(). الطريقة __str__() المستخدمة هي تلك الخاصة بالفئة الفعلية لـ group[i]، كما هو موضح في النتائج أدناه.

النتائج

groupe[0]=[Paul,Langevin,48,anglais]
groupe[1]=[Sylvie,Lefur,70]

5.8. إنشاء فئة ثانية مشتقة من فئة Person


البرنامج (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)

#    ---------------------------------- main
#  create a list of Personne objects and derivatives
groupe=[Enseignant("Paul","Langevin",48,"anglais"), Personne("Sylvie","Lefur",70), Etudiant("Steve","Boer",22,"iup2 qualite")]
#  identity of these persons
for i in range(len(groupe)):
  print "groupe[{0}]={1}".format(i,groupe[i])

ملاحظات:

  • هذا البرنامج النصي مشابه للبرنامج النصي السابق.

النتائج

groupe[0]=[Paul,Langevin,48,anglais]
groupe[1]=[Sylvie,Lefur,70]
groupe[2]=[Steve,Boer,22,iup2 qualite]