Skip to content

Commit ac30266

Browse files
author
Saeid
committed
l19: work on Metaclass
1 parent 8c16523 commit ac30266

3 files changed

Lines changed: 78 additions & 2 deletions

File tree

27.9 KB
Loading

_static/l19-python-metaclass.png

-19.3 KB
Binary file not shown.

lessons/l19.rst

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,8 @@
3030

3131
**متاکلاس (Metaclass)** [`اسناد پایتون <https://docs.python.org/3/reference/datamodel.html#metaclasses>`__] در پایتون یک مفهوم پنهان در رابطه با پیاده‌سازی برنامه‌نویسی شی گرا می‌باشد. اکثر برنامه‌نویس‌ها چه از آن آگاه باشند و چه خیر، به ندرت از آن استفاده می‌کنند و شاید شما هیچگاه نیاز به استفاده از این قابلیت نداشته باشید ولی باید بدانید این قابلیتی است که در اکثر زبان‌های برنامه‌نویسی شی گرا ارائه نمی‌شود!
3232

33-
.. image:: /_static/l19-python-metaclass.png
33+
.. image:: /_static/l19-python-metaclass-type.jpg
3434
:align: center
35-
:target: https://blog.ionelmc.ro/2015/02/09/understanding-python-metaclasses/
3635

3736
**متاکلاس چیست؟** یک کلاس است و اشیایی که از آن ایجاد می‌گردند، کلاس‌ها هستند! بارها گفته شد که «هر چیزی در پایتون یک شی است» و این جمله حتی خود موجودیت کلاس‌ها را نیز شامل می‌شود. با اجرای دستور تعریف کلاس، یک شی از نوع ``type`` در حافظه ایجاد می‌گردد و از نام کلاس برای اشاره به آن شی استفاده می‌شود (درس هفدهم). اکنون می‌توانیم بگوییم که ``type`` در واقع یک متاکلاس می‌باشد::
3837

@@ -101,6 +100,83 @@
101100

102101
برای ایجاد متا کلاس تنها کافی است یک کلاس جدید بسازید که از کلاس ``type`` ارث‌بری داشته باشد. با ارسال نام این کلاس به پارامتر ``metaclass`` هر کلاس دیگری می‌توان به آن‌ها انتساب داد.
103102

103+
بحث اشیای Callable را از درس هفدهم به یاد آورید - هر کلاس در پایتون یک شی از متاکلاس مربوط به خودش می‌باشد، همچنین گفته شد کلاس‌ها در پایتون Callable هستند، بنابراین هرگاه یک کلاس فراخوانی می‌شود (در واقع زمانی که یک شی از آن کلاس ایجاد می‌گردد)، به صورت خودکار متد ``__call__`` متا کلاس آن نیز فراخوانی می‌گردد.
104+
105+
اکنون زمانی است که می‌توانید تمام فرآیند ایجاد یک شی در پایتون را بدانید، آن را در دست بگیرید و هر کاری که نیاز دارید را به انجام برسانید!:
106+
107+
108+
.. code-block:: python
109+
:linenos:
110+
111+
class MetaClass(type):
112+
113+
def __call__(self, *args, **kwargs):
114+
print('\n------->>> MetaClass __call__')
115+
print('self: ', self)
116+
print('args: ', args)
117+
print('kwargs: ', kwargs)
118+
119+
obj = self.__new__(self, *args, **kwargs)
120+
121+
if obj is not None and isinstance(obj, self) and hasattr(obj, '__init__'):
122+
obj.__init__(*args, **kwargs)
123+
124+
return obj
125+
126+
127+
class Sample(metaclass=MetaClass):
128+
129+
def __new__(cls, *args, **kwargs):
130+
print('\n------->>> Sample __new__')
131+
print('cls: ', cls)
132+
print('args: ', args)
133+
print('kwargs: ', kwargs)
134+
135+
obj = super().__new__(cls)
136+
return obj
137+
138+
def __init__(self, x=0, y=0, z=0):
139+
print('\n------->>> Sample __init__')
140+
print('self: ', self)
141+
print('x: ', x)
142+
print('y: ', y)
143+
print('z: ', z)
144+
145+
self.x = x
146+
self.y = y
147+
self.z = z
148+
149+
150+
sample_obj = Sample('p_arg_1', 'p_arg_2', z='k_arg')
151+
152+
153+
154+
::
155+
156+
------->>> MetaClass __call__
157+
self: <class '__main__.Sample'>
158+
args: ('p_arg_1', 'p_arg_2')
159+
kwargs: {'z': 'k_arg'}
160+
161+
------->>> Sample __new__
162+
cls: <class '__main__.Sample'>
163+
args: ('p_arg_1', 'p_arg_2')
164+
kwargs: {'z': 'k_arg'}
165+
166+
------->>> Sample __init__
167+
self: <__main__.Sample object at 0x7f578772f3d0>
168+
x: p_arg_1
169+
y: p_arg_2
170+
z: k_arg
171+
172+
173+
174+
175+
176+
177+
178+
179+
104180
بر اساس تعریف ارائه شده در [`اسناد پایتون <https://docs.python.org/3/glossary.html#term-metaclass>`__]، تعریف کلاس (دستور ``class``) باعث ایجاد «نام کلاس»، «یک شی دیکشنری از کلاس» و «یک شی لیست حاوی superclassهای آن کلاس» می‌شود، متاکلاس این سه آرگومان را دریافت و شی کلاس را ایجاد می‌کند.
105181

106182

0 commit comments

Comments
 (0)