Skip to content

Commit 8c16523

Browse files
author
Saeid
committed
l17: add Callable Objects
1 parent 996613c commit 8c16523

1 file changed

Lines changed: 72 additions & 0 deletions

File tree

lessons/l17.rst

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,78 @@
230230
* ارسال آرگومان در زمان نمونه‌سازی شی یا همان پیاده‌سازی متد ``__init__`` به برنامه‌نویس این اطمینان را می‌دهد که شی جدید در یک وضعیت درست تنظیم شده است.
231231

232232
* آرگومان‌های متناظر با پارامتر‌های متد ``__init__`` (به جز ``self`` که توسط مفسر پایتون مقداردهی می‌گردد) می‌بایست در زمان نمونه‌سازی و فراخوانی کلاس ارسال گردد.
233+
234+
235+
اشیا با قابلیت فراخوانی (Callable Objects)
236+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
237+
238+
پیش‌تر دیدیم که می‌توان توابع را فراخوانی نمود (درس دروازدهم)، با این کار بدنه تابع اجرا و خروجی متناسب دریافت می‌گردید. در این درس نیز مشاهده کردیم کلاس‌ها نیز در پایتون توانایی فراخوانی دارند که با فراخوانی کلاس، یک شی از آن ایجاد می‌گردد. با استفاده از تابع ``callable`` در پایتون می‌توان تشخیص داد که آیا یک شی قابلیت فراخوانی دارد یا خیر [`اسناد پایتون <https://docs.python.org/3/library/functions.html#callable>`__]، این تابع در صورتی که شی دریافتی قابلیت فراخوانی (callable) داشته باشد مقدار ``True`` و در غیر این صورت ``False`` برمی‌گرداند::
239+
240+
>>> def function():
241+
... pass
242+
...
243+
>>> callable(function)
244+
True
245+
246+
>>> class SampleClass:
247+
... pass
248+
...
249+
>>> callable(SampleClass)
250+
True
251+
252+
>>> obj = SampleClass()
253+
>>> callable(obj)
254+
False
255+
256+
>>> obj()
257+
Traceback (most recent call last):
258+
File "<stdin>", line 1, in <module>
259+
TypeError: 'SampleClass' object is not callable
260+
261+
262+
همانطور که از نمونه کد بالا مشخص است، اشیایی که از کلاس‌های خودمان ایجاد می‌کنیم، بر خلاف خود کلاس قابلیت فراخوانی ندارند. در زبان پایتون می‌توانیم این قابلیت را به اشیا کلاس‌های خود اضافه نماییم.
263+
264+
همانطور که اشاره شد، کلاس در پایتون چندین متد خاص همانند ``__new__`` و ``__init__`` دارد که به تدریج به آنها آشنا خواهیم شد. یکی دیگر از این متدها ``__call__`` می‌باشد [`اسناد پایتون <https://docs.python.org/3/reference/datamodel.html#object.__call__>`__]. این متد نیز همانند متد ``__init__`` از نوع Instance Method (*بخش بعدی شرح داده شده است*) می‌باشد که با پیاده‌سازی آن در کلاس، اشیای آن کلاس قابلیت فراخوانی پیدا خواهند کرد:
265+
266+
267+
268+
.. code-block:: python
269+
:linenos:
270+
271+
class Sample:
272+
273+
def __init__(self, x=0, y=0):
274+
print('------------------- Called __init__()')
275+
self.x = x
276+
self.y = y
277+
278+
def __call__(self, x, y):
279+
print('------------------- Called __call__()')
280+
self.x = x
281+
self.y = y
282+
283+
284+
obj = Sample()
285+
print('object is callable:', callable(obj))
286+
print('x =', obj.x)
287+
288+
obj(5, 6)
289+
print('x =', obj.x)
290+
291+
::
292+
293+
------------------- Called __init__()
294+
object is callable: True
295+
x = 0
296+
------------------- Called __call__()
297+
x = 5
298+
299+
300+
سطر ۱۸ نمایش فراخوانی یک شی از کلاس Sample می‌باشد - درست به مانند یک تابع!
301+
302+
با فراخوانی یکی شی، به صورت خودکار متد ``__call__`` فراخوانی و آرگومان‌های نظیر ارسال می‌گردند.
303+
304+
از کاربردهای پیاده‌سازی متد ``__call__`` و افزودن قابلیت فراخوانی به یک شی می‌توان به ایجاد کلاس به عنوان دکوراتور (decorator) اشاره کرد (*دروس آتی شرح داده خواهد شد*) و همچنین کاربردهایی که نیاز می‌شود شی در زمان اجرا initialize یا مقداردهی دوباره داشته باشد، چرا که متد ``__init__`` تنها یکبار در زمان نمونه‌سازی فراخوانی می‌گردد.
233305

234306

235307

0 commit comments

Comments
 (0)