PDA

View Full Version : آموزش شی گرایی در پایتون



laughing
یک شنبه 05 مهر 1394, 18:17 عصر
در پایتون یک کلاس مجموعه‌ای از خصوصیات است که توسط اشیا قابل دسترسی می‌باشد. این خصوصیات شامل توابع (functions)، که به متدها (methods) معروف می‌باشند، متغیرهای کلاسی و property ها می‌باشند.
برای نمونه یک کلاس به‌صورت زیر تعریف می‌شود:


class Account(object):
"A Simple Class"
num_accounts = 0

#................................................
def __init__(self, name, balance):
"Initialize a new Account instance"
self.name = name
self.balance = balance

Account.num_accounts += 1

#................................................
def __del__(self):
Account.num_accounts -= 1

#................................................
def deposit(self, amt):
"Add to the balance"
self.balance = self.balance + amt

#................................................
def withdraw(self, amt):
"Subtract from the balance"
self.balance = self.balance - amt

#................................................
def inquiry(self):
"Return the current balance"
return self.balance




این کلاس سه متغیر به نام های num_accounts ، name و balance دارد.
تابع __init__ در کلاس مانند یک سازنده عمل می کند
همان طور که گفتیم تابع در کلاس را متد می‌گویند. متد تابعی است که روی یک شی‌ای از کلاس اجرا می‌شود و این شی از کلاس را به عنوان پارامتر اول خود در نظر می‌گیرد. به طور قراردادی این پارامتر را self در نظر می‌گیرند، اما هر نام دیگری برای آن می‌توان در نظر گرفت.

ساخت شی از کلاس به‌صورت زیر انجام می‌شود:


object1 = Account("Mohammad", 2313.3)
object2 = Account("Ali", 54)


یک ویژگی جالب کلاس‌ها این است که اشیای پیاده‌سازی شده از یک دیکشنری برای نگهداری اطلاعات خودشان استفاده می‌کنند. این دیکشنری با استفاده از مشخصه __dict__ قابل دسترس است. به عنوان مثال اگر این مشخصه را برای شی object1 فراخوانی و آن را چاپ کنیم:


print(object1.__dict__)


نتیجه زیر را مشاهده می کنیم:


{'balance': 2313.3, 'name': 'Mohammad'}





Reference:Python Essential Reference,Third Edition, Sams Publishing(2006)

laughing
سه شنبه 07 مهر 1394, 12:22 عصر
یک ویژگی بسیار جالب پایتون این است که در پایتون، به یک نمونه یا شی از کلاس می‌توانیم خصوصیت جدید مانند متغیر کلاسی اضافه کنیم. به عنوان مثال به شی object1 از کلاس Account در مثال قبل، متغیر جدید number را اضافه می‌کنیم.


object1.number = 1394 #Add atribute 'number' to object1.__dict__

متغیر و مقدار آن در دیکشنری محلی شی object1 ذخیره می‌شود و هنگامی که دیکشنری محلی را فراخوانی کنیم، می‌توانیم مقدار اضافه شده را مشاهده کنیم:


print(object1.__dict__)

خروجی:


{'balance': 2313.3, 'number': 1394, 'name': 'Mohammad'}

laughing
سه شنبه 07 مهر 1394, 12:33 عصر
اما مانند سایر زبان های برنامه نویسی، یک کلاس در پایتون می تواند مجموعه ثابتی از خصوصیات را داشته باشد که قابل تغییر و اضافه توسط شی نباشد. این کار با تعریف متغیرها به وسیله __slots__ انجام می‌شود. برای مثال در کلاس زیر متغیرهای کلاسی را با استفاده از __slots__ به صورت زیر تعریف کرده ایم.


class Nature(object):
__slots__ = 'type', 'name'

#................................................
def __init__(self, type, name):
self.type = type
self.name = name

وقتی __slots__ تعریف می شود، نام متغیرها در یک شی از کلاس منحصر به این متغیرها می‌شود. با این کار دیگر به تعریف متغیرهای کلاس در دیکشنری __dict__ دسترسی نداریم و آنها در یک ساختمان داده بهینه‌تری ذخیره می‌شوند.

laughing
سه شنبه 07 مهر 1394, 13:09 عصر
ارث‌بری تکنیکی برای ایجاد یک کلاس جدید است، به طوری که خصوصیات یک کلاس دیگر که از قبل ایجاد شده است را داشته باشد و یا بعضی از خصوصیات کلاس قبلی را اصلاح کند. به کلاس اصلی کلاس پایه و به کلاس جدید، کلاس مشتق شده می‌گویند.
هر کلاس در پایتون از کلاس اصلی object ارث می‌برد. به همین علت در پرانتز جلوی تعریف کلاس، object را قرار می‌دهیم.
برای تعریف ارث‌بری،نام کلاس پایه را در پرانتز جلوی کلاس مشتق‌شده قرار می‌دهیم. اگر بخواهیم یک کلاس از چندین کلاس ارث ببرد، نام کلاس‌های پایه را با ویرگول از هم جدا می‌کنیم.
مثال:


class A(object):
def method1(self):
print("Class A : method1")

class B(A): #Inherits from A
def method1(self):
print("class B : method1")
def method2(self):
print("Class B : method2")

class C(B): #Inherits from B
def method3(self):
print("Class C : method3")

class D(A): #Inherits from A
def method1(self):
print("Class D : method1")

class E(B,D): #Inherits from B and D
pass

اگر به دنبال یک خصوصیت باشیم، پایتون ابتدا تعریف کلاس را بررسی می‌کند و سپس به دنبال کلاس‌های پایه می‌رود.


c = C()
c.method3()
c.method1()

e = E()
e.method1()

خروجی:


Class C : method3
class B : method1
class B : method1

پایتون در سلسله مراتب ارث‌بری به دنبال خصوصیت می‌گردد تا نهایتا آن را پیدا کند. در مثال شی c پایتون کلاس‌ها را به ترتیب C و B و A جستجو می‌کند. اما هنگامی که ارث‌بری چندتایی داشته باشیم، ترتیب کلاس‌های پایه هم مهم می‌شود. برای مشاهده ترتیب سلسله مراتب ارث‌بری از دستور زیر می‌توان استفاده کرد:


print(E.__mro__)

که خروجی آن به صورت زیر است:


(<class '__main__.E'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.A'>, <class 'object'>)

laughing
یک شنبه 12 مهر 1394, 10:34 صبح
در این بخش در مورد property صحبت می‌کنیم. در پایتون متغیر خصوصی یا private نداریم. اما در پایتون یک ویژگی جالب به نام property در کلاس تعریف شده است. property ها متغیرهایی در کلاس هستند که برای گرفتن مقدار و یا ثبت مقدار به این متغیرها، توابعی اختصاصی برایشان تعریف می‌شود. به عنوان مثال ممکن است شما در یک کلاس متغیری داشته باشید که مقدار دقیقه را در خود نگهداری می‌کند و می‌خواهید این مقدار بین 0 و 60 باشد. پس با استفاده از تابع درج مقدار به متغیر می‌توانید این دامنه را کنترل کنید.
property به صورت زیر تعریف می‌شود:


property([fget[, fset[, fdel[, doc]]]])

fget : نام تابعی است که مقدار property را بازمی‌گرداند.
fset : نام تابعی است که به property مقدار می‌دهد.
fdel : نام تابعی است که property را حذف می‌کند.
doc : توضیحات برای property

در کلاس زیر یک property تعریف کرده‌ایم:


class C(object):
def __init__(self):
self._x = None

#Return the value of x
def getX(self):
return self._x

#Set the value x
def setX(self, value):
print('setX called')

if value > 0 and value < 60:
self._x = value
print('x has changed')
else:
print('value %s is out of range, then x var has not changed!' % (value))

#Delete x
def delX(self):
del self._x

#Define the property x
x = property(getX, setX, delX, 'Description for property x!!!')


در تابع property توابع get و set و del قرار دارند. هنگامی که کاربر بخواهد مقدار متغیر x را تغییر دهد، تابع مورد نظر بجای آن فراخوانی می‌شود. پس اگر برای مقدار دادن به متغیر x کد زیر را وارد کنید،


c = C()

c.x = 45
print(c.x)

مقدار متغیر x تغییر پیدا خواهد کرد و خروجی زیر را دارید:


setX called
x has changed
45


اما برای دستور زیر:


c.x = 23870
print(c.x)

مقدار متغیر x تغییر نخواهد کرد و خروجی زیر را خواهید داشت:


setX called
value 23870 is out of range, then x var has not changed!
45


Reference : Python Power! The Comprehensive Guide(2008), Matt Telles