Skip to content

Commit 349e333

Browse files
author
Saeid Darvish
committed
l17: completed
1 parent fe90b82 commit 349e333

1 file changed

Lines changed: 78 additions & 25 deletions

File tree

lessons/l17.rst

Lines changed: 78 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
.. role:: emoji-size
22

33
.. meta::
4-
:description: کتاب آموزش زبان برنامه نویسی پایتون به فارسی، آموزش شی گرایی در پایتون، تعریف کلاس در پایتون، ایجاد شی در پایتون، OOP در پایتون
4+
:description: کتاب آموزش زبان برنامه نویسی پایتون به فارسی، آموزش شی گرایی در پایتون، تعریف کلاس در پایتون، معرفی ساختار کلاس در پایتون، تعریف متد Method و صفت Attribute در کلاس‌های پایتون، معرفی Constructor در کلاس پایتون، ایجاد شی و نمونه سازی در پایتون، OOP در پایتون
55
:keywords: آموزش, آموزش پایتون, آموزش برنامه نویسی, پایتون, تابع, کتابخانه, پایتون, شی گرایی در پایتون
66

77

@@ -62,6 +62,7 @@
6262
>>> type(MyClassName)
6363
<class 'type'>
6464

65+
هر چیزی در پایتون یک شی است. حتی کلاس‌ها، با اجرای دستور تعریف کلاس، یک شی از نوع ``type`` در حافظه ایجاد می‌گردد و از نام کلاس برای اشاره به آن شی استفاده می‌شود.
6566

6667
.. tip::
6768
پیشنهاد `PEP 8 <http://www.python.org/dev/peps/pep-0008>`__: برای نوشتن نام کلاس از شیوه CapitalizedWords استفاده شود.
@@ -76,12 +77,26 @@
7677

7778
به بیانی ساده‌تر، هر کلاس می‌تواند شامل تعدادی تابع و متغیر در داخل بدنه خود باشد. که به متغیرها: Attribute و به توابع: Method گفته می‌شود. هر یک از این Attributeها و Methodها انواعی دارند که در ادامه شرح داده خواهد شد.
7879

80+
توجه داشته باشید که تعریف‌هایی با سینتکس زیر نیز از کلاس در زبان برنامه‌نویسی پایتون صحیح می‌باشند. به طور کلی «پرانتر» در جلوی نام کلاس، زمانی قرار می‌گیرد که قصد پیاده‌سازی مفهوم وراثت (درس بعد) را داشته باشیم، در غیر این صورت نیازی به قرار دادن پرانتز نمی‌باشد::
81+
82+
>>> class DerivedClassName(BaseClassName):
83+
... pass
84+
...
85+
>>>
86+
87+
::
88+
89+
>>> class MyClassName():
90+
... pass
91+
...
92+
>>>
93+
7994
نمونه‌سازی (Instantiation)
8095
--------------------------------------------------------
8196

8297
به عملیات ایجاد یک شی از کلاس، **نمونه‌سازی (Instantiation)** گفته می‌شود. کلاس چیزی جز تکه کدی نوشته شده نیست و جایی در حافظه ندارد، این اشیا ایجاد شده از کلاس هستند که در حافظه (Memory) قرار می‌گیرند. نمونه‌سازی از یک کلاس در زبان پایتون به صورت زیر انجام می‌شود::
8398

84-
>>> class Sample():
99+
>>> class Sample:
85100
... pass
86101
...
87102
>>>
@@ -96,6 +111,42 @@
96111
از هر کلاس می‌توان بی‌نهایت نمونه‌سازی داشت. هر شی از یک کلاس، حوزه (Scope) مخصوص به خود را دارد که جدا از دیگر اشیا آن کلاس خواهد بود. بنابراین اشیا هر کلاس کاملا مستقل و ایزوله (isolated) از یکدیگر هستند.
97112

98113

114+
::
115+
116+
>>> class Sample:
117+
... pass
118+
...
119+
>>>
120+
>>> obj_1 = Sample()
121+
>>> obj_2 = Sample()
122+
123+
>>> id(obj_1)
124+
139936512966840
125+
>>> id(obj_2)
126+
139936512967008
127+
128+
همانطور که از خروجی تابع آماده (built-in) ``id`` نیز مشخص است [`اسناد پایتون <https://docs.python.org/3/library/functions.html#id>`__] هر شی جدید از کلاس، identity یا هویتی مستقل از دیگر اشیا داشته و در مکانی جداگانه از حافظه قرار داده شده است.
129+
130+
::
131+
132+
>>> class Sample:
133+
... pass
134+
...
135+
>>> obj = Sample()
136+
137+
138+
>>> type(obj)
139+
<class '__main__.Sample'>
140+
141+
>>> type(obj) == Sample
142+
True
143+
144+
145+
>>> isinstance(obj, Sample)
146+
True
147+
148+
در زبان پایتون دو شیوه رایج برای بررسی نوع یک شی وجود دارد. یک راه استفاده از تابع آماده (built-in) ``type`` است [`اسناد پایتون <https://docs.python.org/3/library/functions.html#type>`__] که پیش‌تر از آن استفاده می‌کردیم و راه دیگر استفاده از تابع آماده (built-in) ``isinstance`` می‌باشد [`اسناد پایتون <https://docs.python.org/3/library/functions.html#isinstance>`__] این تابع دو آرگومان می‌پذیرد که به ترتیب شی و نوع مورد نظر هستند، در صورتی که شی از نوع دریافت شده باشد، مقدار ``True`` و در غیر این صورت ``False`` برمی‌گرداند.
149+
99150
سازنده (Constructor)
100151
~~~~~~~~~~~~~~~~~~~~~~~~~
101152

@@ -106,7 +157,7 @@
106157
در فرآیند نمونه‌سازی از یک کلاس پایتون، به ترتیب دو متد خاص درگیر هستند: ``__new__`` [`اسناد پایتون <https://docs.python.org/3/reference/datamodel.html#object.__new__>`__] و ``__init__`` [`اسناد پایتون <https://docs.python.org/3/reference/datamodel.html#object.__init__>`__]
107158

108159

109-
متد ``__new__`` در زمان ایجاد شی و دقیقا برای ایجاد شی فراخوانی می‌شود، خروجی این متد یک شی جدید از آن کلاس می‌باشد. این متد از نوع Class Method است - *در بخش بعدی شرح داده خواهد شد* - بنابراین نخستین پارامتر این متد کلاس جاری است که قرار است از آن یک شی ایجاد گردد و پارامترهای دیگر که می‌توانند حاوی مقادیری باشد که در زمان نمونه‌سازی ارسال شده است.
160+
متد ``__new__`` در زمان ایجاد شی و دقیقا برای ایجاد شی فراخوانی می‌شود، خروجی این متد یک شی جدید از آن کلاس می‌باشد. این متد از نوع Static Method است - *در بخش بعدی شرح داده خواهد شد* - نخستین پارامتر این متد ،کلاسی است که قرار است از آن یک شی ایجاد گردد و پارامترهای دیگر که می‌توانند حاوی مقادیری باشند که در زمان نمونه‌سازی ارسال شده است.
110161

111162
متد ``__init__`` بلافاصله پس از اینکه شی جدید توسط متد ``__new__`` ایجاد گردید و درست قبل از اینکه شی جدید از متد ``__new__`` بازگردانده شود (returned)، فراخوانی می‌گردد. این متد از نوع Instance Method است - *در بخش بعدی شرح داده خواهد شد* - و بنابراین نخستین پارامتر این متد شی جاری است (همان شی‌ای که توسط ``__new__`` ایجاد گردیده است) و پارامترهای دیگر که برنامه‌نویس در زمان نمونه‌سازی جهت مقدار دهی در شی ارسال می‌کند - توجه داشته باشید که این متد خروجی ندارد (بدون دستور return یا بهتر بگوییم خروجی آن None است) و شی جدید حاصل خروجی متد ``__new__`` خواهد بود.
112163

@@ -115,9 +166,9 @@
115166
.. code-block:: python
116167
:linenos:
117168
118-
class Sample():
169+
class Sample:
119170
120-
def __new__(cls,*args,**kwargs):
171+
def __new__(cls, *args, **kwargs):
121172
print("__new__(), Has been called")
122173
print('cls: ', cls)
123174
print('args: ', args)
@@ -139,6 +190,8 @@
139190
sample_1 = Sample()
140191
print('-' * 30)
141192
sample_2 = Sample(3, 6)
193+
print('-' * 30)
194+
sample_3 = Sample(x=3, y=6)
142195
143196
::
144197

@@ -155,19 +208,29 @@
155208
kwargs: {}
156209
__init__(), Has been called
157210
self: <__main__.Sample object at 0x7fb4580a64e0>
211+
------------------------------
212+
__new__(), Has been called
213+
cls: <class '__main__.Sample'>
214+
args: ()
215+
kwargs: {'x': 3, 'y': 6}
216+
__init__(), Has been called
217+
self: <__main__.Sample object at 0x7fb005453438>
218+
158219

159220
**این مثال صرفا جهت نمایش نقش Constructor و منطق و چگونگی پیاده‌سازی آن در زبان برنامه‌نویسی پایتون ارائه شده است. تمام موارد نا آشنایی که می‌بینید به تدریج شرح داده خواهند شد.**
160221

161222
.. tip::
162223

163-
* زبان برنامه‌نویسی پایتون برخلاف برخی از زبان‌های دیگر شی‌گرا به مانند Java، از امکان پیاده‌سازی چندین Constructor پشتیبانی نمی‌کند.
224+
* زبان برنامه‌نویسی پایتون برخلاف برخی از زبان‌های دیگر شی‌گرا به مانند Java، از امکان پیاده‌سازی چندین Constructor پشتیبانی نمی‌کند. البته برنامه‌نویس با روش‌هایی می‌تواند به صورت منطقی به هدف خود برسد!
164225

165226
* همانطور که بیان شد، هر کلاس پایتون یک پیاده‌سازی پیش‌فرض از دو متد ``__new__`` و ``__init__`` دارد بنابراین الزامی به پیاده‌سازی دو متد ``__new__`` و ``__init__`` برای نمونه‌سازی از کلاس نیست. در اکثر مواقع ``__new__`` پیاده‌سازی نمی‌شود اما زمانی که می‌خواهید در زمان نمونه‌سازی مقادیری در شی تنظیم نمایید، لازم است متد ``__init__`` را پیاده‌سازی نمایید.
166227

167228
* معمولا ``__new__`` زمانی پیاده‌سازی می‌شود که بخواهیم محدودیت‌هایی در ایجاد شی کلاس مورد نظر ایجاد کنیم. برای نمونه در پیاده‌سازی طرح Singleton [`ویکی‌پدیا <https://en.wikipedia.org/wiki/Singleton_pattern>`__] یک کلاس.
168229

169230
* ارسال آرگومان در زمان نمونه‌سازی شی یا همان پیاده‌سازی متد ``__init__`` به برنامه‌نویس این اطمینان را می‌دهد که شی جدید در یک وضعیت درست تنظیم شده است.
170231

232+
* آرگومان‌های متناظر با پارامتر‌های متد ``__init__`` (به جز ``self`` که توسط مفسر پایتون مقداردهی می‌گردد) می‌بایست در زمان نمونه‌سازی و فراخوانی کلاس ارسال گردد.
233+
171234

172235

173236
صفات (Attributes)
@@ -192,7 +255,7 @@ Instance Attribute
192255
.. code-block:: python
193256
:linenos:
194257
195-
class Sample(): pass
258+
class Sample: pass
196259
197260
sample = Sample()
198261
@@ -204,7 +267,7 @@ Instance Attribute
204267

205268
A New Attribute!
206269
207-
هر چیزی در پایتون یک شی است ولی ممکن است مفسر پایتون برای برخی اشیا محدودیت‌هایی در نظر گرفته باشد و شما نتوانید به هر شی‌ای در پایتون Attribute اضافه نمایید. در این لحظه جا دارد اشاره شود به درس چهاردهم (بخش Function Attributes) که در واقع از این قانون اشیا در پایتون پیروی می‌کند.
270+
هر چیزی در پایتون یک شی است ولی ممکن است مفسر پایتون برای برخی اشیا محدودیت‌هایی در نظر گرفته باشد و شما نتوانید به هر شی‌ای در پایتون Attribute اضافه نمایید. در این لحظه جا دارد اشاره شود به درس چهاردهم (بخش Function Attributes) که در واقع کاری جز افزودن Attribute به شی تابع نبود.
208271

209272
.. tip::
210273
مقدار این دسته از Attributeها به ازای هر شی منحصر‌به‌فرد است. برای نمونه صفت‌هایی همچون نام، نام‌خانوادگی، سن و جنسیت برای هر یک از اشیای کلاس «شخص» قابل تعریف است. بدیهی است که هر نمونه شی از این کلاس می‌بایست شامل مقادیر منحصر‌به‌فردی از این Attributeها باشد.
@@ -215,7 +278,7 @@ Instance Attribute
215278
.. code-block:: python
216279
:linenos:
217280
218-
class Sample():
281+
class Sample:
219282
220283
def __init__(self, attribute_value):
221284
self.a_new_attribute = attribute_value
@@ -232,7 +295,7 @@ Instance Attribute
232295
.. code-block:: python
233296
:linenos:
234297
235-
class Person():
298+
class Person:
236299
237300
def __init__(self, first_name, last_name, age, gender):
238301
self.first_name = first_name
@@ -269,7 +332,7 @@ Class Attribute
269332
.. code-block:: python
270333
:linenos:
271334
272-
class Sample():
335+
class Sample:
273336
class_attribute = 0
274337
275338
print('#' * 10, 'STEP#A')
@@ -348,12 +411,12 @@ Class Attribute
348411

349412
* Static Method
350413

351-
هر زمان در پیاده‌سازی یک کلاس، به کلاس و به اشیای آن کلاس نیازی نداشتیم، می‌بایست این نوع متد را پیاده‌سازی کنیم. س
414+
هر زمان در پیاده‌سازی یک کلاس، به کلاس و به اشیای آن کلاس نیازی نداشتیم یا قصد پیاده‌سازی کاری مستقل از رفتار کلی کلاس مورد نظر داشتیم، می‌بایست این نوع متد را پیاده‌سازی کنیم.
352415

353416
.. code-block:: python
354417
:linenos:
355418
356-
class Sample():
419+
class Sample:
357420
358421
def instance_method(self):
359422
pass
@@ -378,7 +441,7 @@ Class Attribute
378441
.. code-block:: python
379442
:linenos:
380443
381-
class Sample():
444+
class Sample:
382445
383446
def __init__(self, char='*'):
384447
self.character = char
@@ -496,23 +559,13 @@ Class Attribute
496559

497560

498561

499-
متدهای جادویی (Magic methods)
500-
-----------------------------------------------------
501-
502-
503-
504-
هر چیزی در پایتون یک شی است
505-
---------------------------------------------------------------------------------------
506-
507-
508-
509562
|
510563
511564
----
512565

513566
:emoji-size:`😊` امیدوارم مفید بوده باشه
514567

515-
`لطفا دیدگاه و سوال‌های مرتبط با این درس خود را در کدرز مطرح نمایید. <https://www.coderz.ir/python-oop/>`_
568+
`لطفا دیدگاه و سوال‌های مرتبط با این درس خود را در کدرز مطرح نمایید. <https://www.coderz.ir/python-tutorial-oop-class-and-object>`_
516569

517570

518571

0 commit comments

Comments
 (0)