You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: lessons/l17.rst
+78-25Lines changed: 78 additions & 25 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,7 @@
1
1
.. role:: emoji-size
2
2
3
3
.. meta::
4
-
:description: کتاب آموزش زبان برنامه نویسی پایتون به فارسی، آموزش شی گرایی در پایتون، تعریف کلاس در پایتون، ایجاد شی در پایتون، OOP در پایتون
4
+
:description: کتاب آموزش زبان برنامه نویسی پایتون به فارسی، آموزش شی گرایی در پایتون، تعریف کلاس در پایتون، معرفی ساختار کلاس در پایتون، تعریف متد Method و صفت Attribute در کلاسهای پایتون، معرفی Constructor در کلاس پایتون، ایجاد شی و نمونه سازی در پایتون، OOP در پایتون
5
5
:keywords: آموزش, آموزش پایتون, آموزش برنامه نویسی, پایتون, تابع, کتابخانه, پایتون, شی گرایی در پایتون
6
6
7
7
@@ -62,6 +62,7 @@
62
62
>>> type(MyClassName)
63
63
<class 'type'>
64
64
65
+
هر چیزی در پایتون یک شی است. حتی کلاسها، با اجرای دستور تعریف کلاس، یک شی از نوع ``type`` در حافظه ایجاد میگردد و از نام کلاس برای اشاره به آن شی استفاده میشود.
65
66
66
67
.. tip::
67
68
پیشنهاد `PEP 8 <http://www.python.org/dev/peps/pep-0008>`__: برای نوشتن نام کلاس از شیوه CapitalizedWords استفاده شود.
@@ -76,12 +77,26 @@
76
77
77
78
به بیانی سادهتر، هر کلاس میتواند شامل تعدادی تابع و متغیر در داخل بدنه خود باشد. که به متغیرها: Attribute و به توابع: Method گفته میشود. هر یک از این Attributeها و Methodها انواعی دارند که در ادامه شرح داده خواهد شد.
78
79
80
+
توجه داشته باشید که تعریفهایی با سینتکس زیر نیز از کلاس در زبان برنامهنویسی پایتون صحیح میباشند. به طور کلی «پرانتر» در جلوی نام کلاس، زمانی قرار میگیرد که قصد پیادهسازی مفهوم وراثت (درس بعد) را داشته باشیم، در غیر این صورت نیازی به قرار دادن پرانتز نمیباشد::
به عملیات ایجاد یک شی از کلاس، **نمونهسازی (Instantiation)** گفته میشود. کلاس چیزی جز تکه کدی نوشته شده نیست و جایی در حافظه ندارد، این اشیا ایجاد شده از کلاس هستند که در حافظه (Memory) قرار میگیرند. نمونهسازی از یک کلاس در زبان پایتون به صورت زیر انجام میشود::
83
98
84
-
>>> class Sample():
99
+
>>> class Sample:
85
100
... pass
86
101
...
87
102
>>>
@@ -96,6 +111,42 @@
96
111
از هر کلاس میتوان بینهایت نمونهسازی داشت. هر شی از یک کلاس، حوزه (Scope) مخصوص به خود را دارد که جدا از دیگر اشیا آن کلاس خواهد بود. بنابراین اشیا هر کلاس کاملا مستقل و ایزوله (isolated) از یکدیگر هستند.
97
112
98
113
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
+
99
150
سازنده (Constructor)
100
151
~~~~~~~~~~~~~~~~~~~~~~~~~
101
152
@@ -106,7 +157,7 @@
106
157
در فرآیند نمونهسازی از یک کلاس پایتون، به ترتیب دو متد خاص درگیر هستند: ``__new__`` [`اسناد پایتون <https://docs.python.org/3/reference/datamodel.html#object.__new__>`__] و ``__init__`` [`اسناد پایتون <https://docs.python.org/3/reference/datamodel.html#object.__init__>`__]
107
158
108
159
109
-
متد ``__new__`` در زمان ایجاد شی و دقیقا برای ایجاد شی فراخوانی میشود، خروجی این متد یک شی جدید از آن کلاس میباشد. این متد از نوع Class Method است - *در بخش بعدی شرح داده خواهد شد* - بنابراین نخستین پارامتر این متد کلاس جاری است که قرار است از آن یک شی ایجاد گردد و پارامترهای دیگر که میتوانند حاوی مقادیری باشد که در زمان نمونهسازی ارسال شده است.
160
+
متد ``__new__`` در زمان ایجاد شی و دقیقا برای ایجاد شی فراخوانی میشود، خروجی این متد یک شی جدید از آن کلاس میباشد. این متد از نوع Static Method است - *در بخش بعدی شرح داده خواهد شد* - نخستین پارامتر این متد ،کلاسی است که قرار است از آن یک شی ایجاد گردد و پارامترهای دیگر که میتوانند حاوی مقادیری باشند که در زمان نمونهسازی ارسال شده است.
110
161
111
162
متد ``__init__`` بلافاصله پس از اینکه شی جدید توسط متد ``__new__`` ایجاد گردید و درست قبل از اینکه شی جدید از متد ``__new__`` بازگردانده شود (returned)، فراخوانی میگردد. این متد از نوع Instance Method است - *در بخش بعدی شرح داده خواهد شد* - و بنابراین نخستین پارامتر این متد شی جاری است (همان شیای که توسط ``__new__`` ایجاد گردیده است) و پارامترهای دیگر که برنامهنویس در زمان نمونهسازی جهت مقدار دهی در شی ارسال میکند - توجه داشته باشید که این متد خروجی ندارد (بدون دستور return یا بهتر بگوییم خروجی آن None است) و شی جدید حاصل خروجی متد ``__new__`` خواهد بود.
112
163
@@ -115,9 +166,9 @@
115
166
.. code-block:: python
116
167
:linenos:
117
168
118
-
classSample():
169
+
classSample:
119
170
120
-
def__new__(cls,*args,**kwargs):
171
+
def__new__(cls,*args,**kwargs):
121
172
print("__new__(), Has been called")
122
173
print('cls: ', cls)
123
174
print('args: ', args)
@@ -139,6 +190,8 @@
139
190
sample_1 = Sample()
140
191
print('-'*30)
141
192
sample_2 = Sample(3, 6)
193
+
print('-'*30)
194
+
sample_3 = Sample(x=3, y=6)
142
195
143
196
::
144
197
@@ -155,19 +208,29 @@
155
208
kwargs: {}
156
209
__init__(), Has been called
157
210
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
+
158
219
159
220
**این مثال صرفا جهت نمایش نقش Constructor و منطق و چگونگی پیادهسازی آن در زبان برنامهنویسی پایتون ارائه شده است. تمام موارد نا آشنایی که میبینید به تدریج شرح داده خواهند شد.**
160
221
161
222
.. tip::
162
223
163
-
* زبان برنامهنویسی پایتون برخلاف برخی از زبانهای دیگر شیگرا به مانند Java، از امکان پیادهسازی چندین Constructor پشتیبانی نمیکند.
224
+
* زبان برنامهنویسی پایتون برخلاف برخی از زبانهای دیگر شیگرا به مانند Java، از امکان پیادهسازی چندین Constructor پشتیبانی نمیکند. البته برنامهنویس با روشهایی میتواند به صورت منطقی به هدف خود برسد!
164
225
165
226
* همانطور که بیان شد، هر کلاس پایتون یک پیادهسازی پیشفرض از دو متد ``__new__`` و ``__init__`` دارد بنابراین الزامی به پیادهسازی دو متد ``__new__`` و ``__init__`` برای نمونهسازی از کلاس نیست. در اکثر مواقع ``__new__`` پیادهسازی نمیشود اما زمانی که میخواهید در زمان نمونهسازی مقادیری در شی تنظیم نمایید، لازم است متد ``__init__`` را پیادهسازی نمایید.
166
227
167
228
* معمولا ``__new__`` زمانی پیادهسازی میشود که بخواهیم محدودیتهایی در ایجاد شی کلاس مورد نظر ایجاد کنیم. برای نمونه در پیادهسازی طرح Singleton [`ویکیپدیا <https://en.wikipedia.org/wiki/Singleton_pattern>`__] یک کلاس.
168
229
169
230
* ارسال آرگومان در زمان نمونهسازی شی یا همان پیادهسازی متد ``__init__`` به برنامهنویس این اطمینان را میدهد که شی جدید در یک وضعیت درست تنظیم شده است.
170
231
232
+
* آرگومانهای متناظر با پارامترهای متد ``__init__`` (به جز ``self`` که توسط مفسر پایتون مقداردهی میگردد) میبایست در زمان نمونهسازی و فراخوانی کلاس ارسال گردد.
233
+
171
234
172
235
173
236
صفات (Attributes)
@@ -192,7 +255,7 @@ Instance Attribute
192
255
.. code-block:: python
193
256
:linenos:
194
257
195
-
classSample(): pass
258
+
classSample: pass
196
259
197
260
sample = Sample()
198
261
@@ -204,7 +267,7 @@ Instance Attribute
204
267
205
268
A New Attribute!
206
269
207
-
هر چیزی در پایتون یک شی است ولی ممکن است مفسر پایتون برای برخی اشیا محدودیتهایی در نظر گرفته باشد و شما نتوانید به هر شیای در پایتون Attribute اضافه نمایید. در این لحظه جا دارد اشاره شود به درس چهاردهم (بخش Function Attributes) که در واقع از این قانون اشیا در پایتون پیروی میکند.
270
+
هر چیزی در پایتون یک شی است ولی ممکن است مفسر پایتون برای برخی اشیا محدودیتهایی در نظر گرفته باشد و شما نتوانید به هر شیای در پایتون Attribute اضافه نمایید. در این لحظه جا دارد اشاره شود به درس چهاردهم (بخش Function Attributes) که در واقع کاری جز افزودن Attribute به شی تابع نبود.
208
271
209
272
.. tip::
210
273
مقدار این دسته از Attributeها به ازای هر شی منحصربهفرد است. برای نمونه صفتهایی همچون نام، نامخانوادگی، سن و جنسیت برای هر یک از اشیای کلاس «شخص» قابل تعریف است. بدیهی است که هر نمونه شی از این کلاس میبایست شامل مقادیر منحصربهفردی از این Attributeها باشد.
هر زمان در پیادهسازی یک کلاس، به کلاس و به اشیای آن کلاس نیازی نداشتیم، میبایست این نوع متد را پیادهسازی کنیم. س
414
+
هر زمان در پیادهسازی یک کلاس، به کلاس و به اشیای آن کلاس نیازی نداشتیم یا قصد پیادهسازی کاری مستقل از رفتار کلی کلاس مورد نظر داشتیم، میبایست این نوع متد را پیادهسازی کنیم.
0 commit comments