Skip to content

Commit f968a6a

Browse files
author
Saeid Darvish
committed
l17: Constructor
1 parent bd8fc69 commit f968a6a

1 file changed

Lines changed: 72 additions & 1 deletion

File tree

lessons/l17.rst

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,11 @@
7171
.. tip::
7272
یک کلاس، تعریف کننده صفات (ویژگی‌ها) - که به عنوان Attribute شناخته می‌شوند - و رفتار‌های (عملیات) - که به عنوان Method شناخته می‌شوند - اشیایی است که از آن ایجاد خواهد شد. در واقع نام کلاس معرف نوع (type) اشیای خود است.
7373

74+
7475
نمونه‌سازی (Instantiation)
7576
--------------------------------------------------------
7677

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

7980
>>> class Sample():
8081
... pass
@@ -91,6 +92,76 @@
9192
از هر کلاس می‌توان بی‌نهایت نمونه‌سازی داشت. هر شی از یک کلاس، حوزه (Scope) مخصوص به خود را دارد که جدا از دیگر اشیا آن کلاس خواهد بود. بنابراین اشیا هر کلاس کاملا مستقل و ایزوله (isolated) از یکدیگر هستند.
9293

9394

95+
سازنده (Constructor)
96+
~~~~~~~~~~~~~~~~~~~~~~~~~
97+
98+
در مبحث شی‌گرایی، هنگام ساخت یک شی (ایجاد یک نمونه جدید)، به صورت خودکار یک متد از داخل کلاس مورد نظر فراخوانی می‌شود. به این متد **سازنده (Constructor)** گفته می‌شود. فراخوانی خودکار این متد به برنامه‌نویس این امکان را می‌دهد که در صورت تمایل بتواند شی جدید از کلاس مورد نظر را در همان هنگام ساخت، شخصی‌سازی نماید.
99+
100+
از طرفی هر کلاس در زبان برنامه‌نویسی پایتون شامل یک سری متد خاص می‌باشد که نام تمام آن‌ها با دو کاراکتر خط‌زیرین (Underscore or Underline ``_``) شروع و نیز پایان می‌یابد همانند: ``__init__`` - در کامیونیتی پایتون به دو کاراکتر خط‌زیرین در کنار هم به اصطلاح **Dunder** (Double underscores) گفته می‌شود - به این متدهای خاص در پایتون به اصطلاح Special Methods ،Dunder Methods یا Magic Methods گفته می‌شود. [`اسناد پایتون <https://docs.python.org/3/reference/datamodel.html#basic-customization>`__] باید توجه داشت که تمام این متدها یک پیاده‌سازی پیش‌فرض در پایتون دارند و الزامی به پیاده‌سازی از سوی پایتون برای برنامه‌نویس نمی‌باشد.
101+
102+
در فرآیند نمونه‌سازی از یک کلاس پایتون، به ترتیب دو متد خاص درگیر هستند: ``__new__`` [`اسناد پایتون <https://docs.python.org/3/reference/datamodel.html#object.__new__>`__] و ``__init__`` [`اسناد پایتون <https://docs.python.org/3/reference/datamodel.html#object.__init__>`__]
103+
104+
105+
متد ``__new__`` در زمان ایجاد شی و دقیقا برای ایجاد شی فراخوانی می‌شود، خروجی این متد یک شی جدید از آن کلاس می‌باشد. این متد از نوع Static Method است - *در بخش بعدی شرح داده خواهد شد* - بنابراین نخستین پارامتر این متد کلاس جاری است که قرار است از آن یک شی ایجاد گردد و پارامترهای دیگر که می‌توانند حاوی مقادیری باشد که در زمان نمونه‌سازی ارسال شده است.
106+
107+
متد ``__init__`` بلافاصله پس از اینکه شی جدید توسط متد ``__new__`` ایجاد گردید و درست قبل از اینکه شی جدید از متد ``__new__`` بازگردانده شود (returned)، فراخوانی می‌گردد. این متد از نوع Instance Method است - *در بخش بعدی شرح داده خواهد شد* - و بنابراین نخستین پارامتر این متد شی جاری است (همان شی‌ای که توسط ``__new__`` ایجاد گردیده است) و پارامترهای دیگر که برنامه‌نویس در زمان نمونه‌سازی جهت مقدار دهی در شی ارسال می‌کند - توجه داشته باشید که این متد خروجی ندارد (بدون دستور return یا بهتر بگوییم خروجی آن None است) و شی جدید حاص خروجی متد ``__new__`` خواهد بود.
108+
109+
متاسفانه برخی افراد تازه وارد در زبان پایتون و همینطور برخی آموزش‌ها متد ``__init__`` را به عنوان Constructor کلاس‌های پایتون می‌دانند اما درست این است که در فرآیند نمونه‌سازی در زبان برنامه‌نویسی پایتون، دو متد ``__new__`` و ``__init__`` با یکدیگر کار می‌کنند و نقش سازنده (Constructor) را ایفا می‌کنند. متد ``__new__`` شی را ایجاد (create) و متد ``__init__`` آن را شحصی‌سازی (customize) می‌کند:
110+
111+
.. code-block:: python
112+
:linenos:
113+
114+
class Sample():
115+
116+
def __new__(cls,*args,**kwargs):
117+
print("__new__(), Has been called")
118+
print('cls: ', cls)
119+
print('args: ', args)
120+
print('kwargs: ', kwargs)
121+
122+
# create new object
123+
obj = super().__new__(cls)
124+
125+
# return object
126+
return obj
127+
128+
def __init__(self, x=0, y=0):
129+
print("__init__(), Has been called")
130+
print('self: ', self)
131+
self.x = x
132+
self.y = y
133+
134+
135+
sample_1 = Sample()
136+
print('-' * 30)
137+
sample_2 = Sample(3, 6)
138+
139+
::
140+
141+
__new__(), Has been called
142+
cls: <class '__main__.Sample'>
143+
args: ()
144+
kwargs: {}
145+
__init__(), Has been called
146+
self: <__main__.Sample object at 0x7fb4580a6470>
147+
------------------------------
148+
__new__(), Has been called
149+
cls: <class '__main__.Sample'>
150+
args: (3, 6)
151+
kwargs: {}
152+
__init__(), Has been called
153+
self: <__main__.Sample object at 0x7fb4580a64e0>
154+
155+
**این مثال صرفا جهت نمایش نقش Constructor و منطق و چگونگی پیاده‌سازی آن در زبان برنامه‌نویسی پایتون ارائه شده است. تمام موارد نا آشنایی که می‌بینید به تدریج شرح داده خواهند شد.**
156+
157+
.. tip::
158+
159+
* زبان برنامه‌نویسی پایتون برخلاف برخی از زبان‌های دیگر شی‌گرا به مانند Java، از امکان پیاده‌سازی چندین Constructor پشتیبانی نمی‌کند.
160+
161+
* همانطور که بیان شد، هر کلاس پایتون یک پیاده‌سازی پیش‌فرض از دو متد ``__new__`` و ``__init__`` دارد بنابراین الزامی به پیاده‌سازی دو متد ``__new__`` و ``__init__`` برای نمونه‌سازی از کلاس نیست. در اکثر مواقع ``__new__`` پیاده‌سازی نمی‌شود اما زمانی که می‌خواهید در زمان نمونه‌سازی مقادیری در شی تنظیم نمایید، لازم است متد ``__init__`` را پیاده‌سازی نمایید.
162+
163+
* معمولا ``__new__`` زمانی پیاده‌سازی می‌شود که بخواهیم محدودیت‌هایی در ایجاد شی کلاس مورد نظر ایجاد کنیم. برای نمونه در پیاده‌سازی طرح Singleton [`ویکی‌پدیا <https://en.wikipedia.org/wiki/Singleton_pattern>`__] یک کلاس.
164+
94165

95166
متد (Method)
96167
-----------------------------------------------------

0 commit comments

Comments
 (0)