مشخصات مقاله
-
621
-
0.0
-
2624
-
0
-
0
نگاه اولیه به کلاس ها در پایتون
نگاه اولیه به کلاس ها در برنامه نویسی Python
کلاس ها مقدار کمی نحو(syntax) جدید را معرفی می کنند، از جمله سه نوع شی جدید و برخی مفاهیم(semantics) جدید.
آموزش نحوه تعریف کلاس در Python
ساده ترین حالت تعریف کلاس به صورت زیر است:
class ClassName:
.
.
.
تعاریف کلاس، مانند تعاریف تابع(عبارت def) باید پیش از اینکه اثری داشته باشند، اجرا شوند. (می توانید تعریف یک کلاس را در شاخه ای از یک عبارت if یا درون یک تابع قرار دهید.)
در عمل، عبارات درون تعریف یک کلاس، معمولا تعاریف تابع خواهند بود، اما عبارات دیگر نیز مجار هستند و گاهی مفید—بعدا به این موضوع خواهیم پرداخت. تعاریف تابع درون یک کلاس معمولا یک شکل عجیبی از لیست آرگومان ها دارند، که توسط قراردادهای فراخوانی متدها نوشته شده اند—دوباره می گویم، این موضع بعدا توضیح داده خواهد شد.
وقتی تعریف یک کلاس وارد شود، یک فضای نام جدیدی ساخته می شود و به عنوان حوزه محلی استفاده می شود—بنابراین، تمامی تخصیص ها به متغیر های محلی، به این فضای نام جدید می روند. به خصوص، تعاریف تابع، نام تابع جدید را در اینجا اتصال می دهند.
زمانی که تعریف یک کلاس به صورت نرمال قرار گیرد(از طریق پایان)، یک شی کلاس ساخته می شود. این اساسا یک بسته بندی حول محتویات فضای نامی است که توسط تعریف کلاس ایجاد شده است. در بخش بعدی مباحث بیشتری درباره اشیای کلاس فرا خواهیم گرفت. حوزه محلی اصلی ( حوزه ای که دقیقا قبل از تعریف کلاس وارد شده است) باز گردانده شده است، و شی کلاس، به نام کلاس که در سربرگ تعریف کلاس است، محدود شده است. (ClassName در مثال).
آموزش اشیای کلاس در Python
آموزش Class Objects در پایتون
اشیای کلاس از دو نوع عملیات پشتیبانی می کنند: ارجاع های ویژگی (attribute references) و نمونه گیری (instantiation).
ارجاع های ویژگی، از نحوه نگارش استاندارد مورد استفاده برای تمامی ارجاع های ویژگی در پایتون، استفاده می کنند: obj.name . تمامی نام های موجود در فضای نام کلاس، در زمان ساخت شی کلاس، نام های معتبر ویژگی هستند. بنابراین اگر تعریف کلاس به صورت زیر باشد:
class MyClass:
"""A simple example class"""
i = 12345
def f(self):
return 'hello world'
پس MyClass.i و MyClass.f ارجاع های ویژگی معتبر هستند، که به ترتیب یک عدد صحیح و یک شی تابع را باز می گردانند. همچنین می توان به ویژگی های کلاس مقداری را تخصیص داد، بنابراین می توانید مقدار MyClass.i را با تخصیص، تغییر دهید. __doc__ نیز یک ویژگی معتبر است، که docstring متعلق به کلاس "A simple example class" را باز می گرداند. نمونه گیری کلاس از نمادگذاری تابع استفاده می کند. فقط وانمود کنید که شی کلاس یک تابع بدون پارامتر است که یک نمونه جدید از کلاس را باز می گرداند. برای مثال(کلاس بالا را در نظر بگیرید):
x = MyClass()
عبارت بالا یک نمونه جدید از کلاس را ایجاد می کند و این شی را به متغیر محلی x تخصیص می دهد. عمل نمونه گیری (صدا زدن یک شی کلاس) یک شی خالی را ایجاد می کند. بسیاری از کلاس ها، تمایل به ایجاد اشیا با نمونه هایی که برای یک حالت اولیه خاص سفارشی شده باشند، دارند. بنابراین ممکن است یک کلاس یک متد خاص به نام __init__() را به صورت زیر تعریف کند:
def __init__(self):
self.data = []
زمانی که یک کلاس متد __init__() را تعریف می کند، نمونه گیری کلاس، به صورت خودکار __init__() را برای نمونه تازه ساخته شده کلاس فراخوانی می کند. بنابراین در این مثال، یک نمونه جدید و مقدار دهی اولیه شده توسط عبارت زیر قابل دستیابی است:
x = MyClass()
البته که متد __init__() میتواند برای انعطاف پذیری بیشتر دارای آرگومان باشد. در این صورت، آرگومان های داده شده به عملگر نمونه گیری کلاس، به __init__() پاس داده می شوند. برای مثال:
>>> class Complex:
... def __init__(self, realpart, imagpart):
... self.r = realpart
... self.i = imagpart
...
>>> x = Complex(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)
آموزش اشیای نمونه (instance objects) در Python
حال با اشیای نمونه چه کار می توان کرد؟ تنها عملیات قابل فهم توسط اشیای نمونه، ارجاع های ویژگی هستند. دو نوع نام ویژگی معتبر وجود دارد: ویژگی های داده (data attributes) و متدها.
ویژگی های داده” متناظر است با “متغیر های نمونه” در Smalltalk و "اعضای داده” در C++ . ویژگی های داده نیازی به اعلان شدن ندارند؛ آنها همانند متغیر های محلی، در اولین جایی که مقداری به آنها تخصیص یابد، به وجود می آیند. برای مثال، اگر x نمونه MyClass که در بالا ایجاد شد، باشد، قطعه کد زیر مقدار 16 را بدون برجای گذاشتن ردی چاپ خواهد کرد.
x.counter = 1
while x.counter < 10:
x.counter = x.counter * 2
print(x.counter)
del x.counter
نوع دیگری از ارجاع ویژگی نمونه (instance attribute reference)، متد است.
. یک متد تابعی است که متعلق به یک شی است. ( در پایتون، واژه متد تنها مختص به نمونه های کلاس نیست: سایر انواع شی هم می توانند متد داشته باشند. برای مثال، اشیای لیست، متدهایی به نام های append ، insert ، remove ، sort و غیره دارند. اگر چه در مباحث بعدی منحصرا از واژه متد برای بیان متدهای اشیای نمونه کلاس استفاده می شود، مگر اینکه صریحا خلاف آن بیان شود.)
نام های معتبر متد مربوط به یک شی نمونه، به کلاس آن بستگی دارد. در تعریف، تمامی ویژگی های یک کلاس که اشیای تابع هستند، متدهای متناظر با نمونه های آن را تعریف می کنند. بنابراین در مثال ما، از آنجایی که MyClass.f یک تابع است، x.f یک ارجاع معتبر متد است. اما x.i (معتبر)نیست، زیرا MyClass.i (یک تابع) نیست. اما x.f چیزی مشابه MyClass.f نیست—این یک شی متد است، نه یک شی تابع.
آموزش اشیای متد (method objects) در Python
معمولا یک متد دقیقا پس از بسته شدن (bound)، فراخوانی می شود:
x.f()
در مثال MyClass ، رشته 'hello world' باز گردانده می شود. اگر چه، فراخوانی بلافاصله یک متد، ضروری نیست: x.f یک شی متد است، و می تواند در زمانی دیگر ذخیره و صدا زده شود. برای مثال:
xf = x.f
while True:
print(xf())
تا آخر زمان به چاپ hello world ادامه می دهد. زمانی که یک متد فراخوانی می شود، دقیقا چه اتفاقی می افتد؟ ممکن است متوجه شده باشید که x.f() در بالا بدون آرگومان فراخوانی شده است، هر چند که تعریف تابع برای f() یک آرگومان مشخص کرده است. چه اتفاقی برای آرگومان افتاد؟ زمانی که تابعی نیاز به یک آرگومان دارد و بدون آرگومان فراخوانی می شود، پایتون حتما استثنایی را اعلام می کند—حتی اگر آن آرگومان واقعا استفاده نشده باشد.
در واقع ممکن است پاسخ را حدس زده باشید: نکته خاص درباره متد ها این است که شی نمونه به عنوان اولین آرگومان تابع پاس داده می شود. در مثال ما، فراخوانی x.f() دقیقا برابر با فراخوانی MyClass.f(x) است. به طور کلی، فراخوانی یک متد با لیستی از n آرگومان، برابر است با فراخوانی تابع متناظر آن، با لیستی از آرگومان ها که به واسطه درج شی نمونه متد، قبل از اولین آرگومان ساخته شده است.
اگر همچنان متوجه نحوه عملکرد متدها نمی شوید، نگاهی به پیاده سازی احتمالا میتواند قضیه را روشن کند. زمانی که یک ویژگی غیر داده از یک نمونه، ارجاع یافته باشد، کلاس نمونه جستجو می شود. اگر نام، یک ویژگی کلاس معتبر که یک شی تابع است را نشان دهد، یک شی متد به واسطه جمع کردن(اشاره گر ها به) شی نمونه و شی تابع که با هم در یک شی abstract پیدا شده اند، ساخته میشود: این شی متد است. زمانی که شی متد به همراه لیستی از آرگومان ها فراخوانی شده باشد، یک لیست آرگومان جدید از شی نمونه و لیست آرگومان ها ساخته می شود، و شی تابع با لیست آرگومان جدید فراخوانی می شود.
آموزش متغیر های کلاس و نمونه در برنامه نویسی Python
به طور کلی، متغیر های نمونه برای داده هستند و برای هر نمونه یکتا هستند. متغیر های کلاس برای ویژگی ها و متدها هستند و بین همه نمونه های کلاس به اشتراک گذاشته می شوند.
class Dog:
kind = 'canine' # class variable shared by all instances
def __init__(self, name):
self.name = name # instance variable unique to each instance
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.kind # shared by all dogs
'canine'
>>> e.kind # shared by all dogs
'canine'
>>> d.name # unique to d
'Fido'
>>> e.name # unique to e
'Buddy'
همانطور که در بخش سخنی درباره نام ها و اشیا بحث شد، داده های اشتراکی می توانند تاثیرات احتمالی شگفت انگیزی با اشیای تغییر پذیر درگیر مانند لیست ها و دیکشنری ها داشته باشند. برای مثال، لیست tricks در کد زیر نباید به عنوان متغیر کلاس استفاده شود زیرا تنها یک لیست توسط همه نمونه های Dog به اشتراک گذاشته می شود.
class Dog:
tricks = [] # mistaken use of a class variable
def __init__(self, name):
self.name = name
def add_trick(self, trick):
self.tricks.append(trick)
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.add_trick('roll over')
>>> e.add_trick('play dead')
>>> d.tricks # unexpectedly shared by all dogs
['roll over', 'play dead']
طراحی صحیح کلاس، باید به جای آن از یک متغیر نمونه استفاده کند.
class Dog:
def __init__(self, name):
self.name = name
self.tricks = [] # creates a new empty list for each dog
def add_trick(self, trick):
self.tricks.append(trick)
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.add_trick('roll over')
>>> e.add_trick('play dead')
>>> d.tricks
['roll over']
>>> e.tricks
['play dead']