Skip to content

5. کلاس‌ها و اشیاء

یک کلاس قالبی است که اشیاء از روی آن ایجاد می‌شوند. به یک شیء، نمونهٔ یک کلاس گفته می‌شود.

  

5.1. یک کلاس شیء


برنامه (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)
# ارجاع object1 را به object2 اختصاص می‌دهد
obj2=obj1
# obj2 را تغییر می‌دهد
obj2.attr2=0
#هر دو شیء را نمایش می‌دهد
print "objet1=[{0},{1}]".format(obj1.attr1,obj1.attr2)
print "objet2=[{0},{1}]".format(obj2.attr1,obj2.attr2)

یادداشت‌ها:

  • خط ۴: شکل دیگری از نظر. این مورد که با سه ' شروع می‌شود، می‌تواند چندین خط را در بر بگیرد؛
  • خطوط ۳–۴: یک کلاس شیء خالی؛
  • خط ۷: نمونه‌سازی کلاس Objet;
  • خط ۱۷: کپی کردن ارجاعات. متغیرهای 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:
    #ویژگی‌های کلاس
    # اعلام نشده است – می‌تواند به‌صورت پویا ایجاد شود

    # متد
    def identite(self):
        #ظاهراً از ویژگی‌های موجود استفاده نمی‌کند
        return "[{0},{1},{2}]".format(self.prenom,self.nom,self.age)

# ---------------------------------- اصلی
# ویژگی‌ها عمومی هستند و می‌توانند به‌صورت پویا ایجاد شوند
p=Personne()
p.prenom="Paul"
p.nom="Langevin"
p.age=48
# فراخوانی متد
print "personne={0}\n".format(p.identite())

یادداشت‌ها:

  • خطوط ۳–۱۰: یک کلاس با یک متد؛
  • خط ۸: هر متد یک کلاس باید به‌عنوان اولین پارامتر خود شیء self را داشته باشد که به شیء فعلی اشاره می‌کند.

نتایج

personne=[Paul,Langevin,48]

5.3. کلاس Person با یک سازنده


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

# ---------------------------------- اصلی
# یک شیء Person
p=Personne("Paul","Langevin",48)
# فراخوانی متد
print "personne={0}\n".format(p.identite())

یادداشت‌ها:

  • خط ۶: سازنده کلاس __init__ فراخوانی می‌شود. مانند سایر متدها، اولین پارامتر آن self است؛
  • خط ۱۸: یک شیء Personne با استفاده از سازنده کلاس ایجاد می‌شود.

نتایج

personne=[Paul,Langevin,48]

5.4. کلاس Person با بررسی‌های اعتبار در سازنده


برنامه (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)
      
# ---------------------------------- دست
# یک شیء Person
try:
    p=Personne("  Paul  ","  Langevin  ",48)
    print "personne={0}".format(p)
except MyError, erreur:
    print erreur
# یک شیء Person دیگر
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

یادداشت‌ها:

  • خطوط ۷–۸: کلاسی به نام MyError که از کلاس Exception مشتق شده است. این کلاس هیچ قابلیت جدیدی به کلاس اصلی اضافه نمی‌کند. وجود آن تنها برای ارائه یک استثنای سفارشی است؛
  • خط ۱۳: سازنده برای پارامترهای خود مقادیر پیش‌فرض دارد. بنابراین، عملیات p=Personne() معادل p=Person("x", "x", 0); است.
  • خطوط ۱۵–۹: پارامتر prenom بررسی می‌شود. این پارامتر نباید خالی باشد. در غیر این صورت، استثنای MyError همراه با یک پیام خطا ایجاد می‌شود؛
  • خطوط 21–25: همین امر در مورد نام نیز صدق می‌کند؛
  • خطوط ۲۷–۳۱: بررسی سن؛
  • خطوط ۳۳–۳۴: تابع __str__ جایگزین متدی می‌شود که قبلاً با نام identite شناخته می‌شد؛
  • خطوط ۳۸–۴۲: نمونه‌سازی یک شخص، و سپس نمایش هویت او؛
  • خط ۳۹: نمونه‌سازی؛
  • خط ۴۰: نمایش. این عملیات نیاز دارد که شخص p به صورت یک رشته نمایش داده شود. تفسیرگر پایتون سپس به طور خودکار متد p.__str__() را در صورت وجود فراخوانی می‌کند. این متد همان هدف متد toString() در جاوا یا در زبان‌های .NET را برآورده می‌کند؛
  • خطوط ۴۱–۴۲: رسیدگی به هر استثنای نوع MyError. سپس پیام خطای مرتبط با استثنا نمایش داده می‌شود؛
  • خطوط ۴۴–۴۸: همین امر در مورد یک نمونه دوم که با پارامترهای نادرست ایجاد شده است نیز صدق می‌کند؛
  • خطوط ۵۰–۵۴: همین امر در مورد نمونه سوم که با پارامترهای پیش‌فرض ایجاد شده است نیز صدق می‌کند.

نتایج

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

# -------------------
# یک کلاس استثنای مالک
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
# یک شیء Person
try:
    p0=Personne("  Paul  ","  Langevin  ",48)
    print "personne={0}".format(p0)
except MyError, erreur:
    print erreur
# یک شیء Person دیگر
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

یادداشت‌ها:

  • تفاوت با اسکریپت قبلی در خطوط ۳۵–۳۷ است. متد initWithPersonne اضافه شده است. این متد کَنستراکتور __init__ را فراخوانی می‌کند. برخلاف زبان‌های تایپ‌شده، امکان وجود متدهایی با نام یکسان که با ماهیت پارامترها یا مقادیر بازگشتی‌شان از یکدیگر متمایز شوند، وجود ندارد. بنابراین، امکان داشتن چندین سازنده که شیء را از روی پارامترهای مختلف ایجاد کنند، در این مورد شیئی از نوع Personne، وجود ندارد.

نتایج

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
# ایجاد یک لیست از اشیاء Person
groupe=[Personne("Paul","Langevin",48), Personne("Sylvie","Lefur",70)]
# هویت این افراد
for i in range(len(groupe)):
  print "groupe[{0}]={1}".format(i,groupe[i])

یادداشت‌ها:

  • خطوط ۳–۵: کلاس Personne، همان‌طور که قبلاً توضیح داده شد

نتایج

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)
  

# ---------------------------------- اصلی
# ایجاد یک لیست از اشیاء Person و مشتقات آن
groupe=[Enseignant("Paul","Langevin",48,"anglais"), Personne("Sylvie","Lefur",70)]
# هویت این افراد
for i in range(len(groupe)):
  print "groupe[{0}]={1}".format(i,groupe[i])

یادداشت‌ها:

  • خطوط ۵–۶: کلاس Personne که قبلاً تعریف شده است؛
  • خط ۸: کلاس Enseignant را به‌عنوان زیرکلاس کلاس Person اعلام می‌کند؛
  • خط ۱۰: سازنده کلاس مشتق Enseignant باید سازنده کلاس والد Personne را فراخوانی کند؛
  • خطوط ۲۱–۲۲: برای نمایش groupe[i]، مفسر از متد groupe[i].\_\_str\_\_() استفاده می‌کند. متد __str__() مورد استفاده متعلق به کلاس واقعی groupe[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)

# ---------------------------------- اصلی
# ایجاد یک لیست از اشیاء Person و مشتقات
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])

یادداشت‌ها:

  • این اسکریپت مشابه مورد قبلی است.

نتایج

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