|
30 | 30 |
|
31 | 31 | **متاکلاس (Metaclass)** [`اسناد پایتون <https://docs.python.org/3/reference/datamodel.html#metaclasses>`__] در پایتون یک مفهوم پنهان در رابطه با پیادهسازی برنامهنویسی شی گرا میباشد. اکثر برنامهنویسها چه از آن آگاه باشند و چه خیر، به ندرت از آن استفاده میکنند و شاید شما هیچگاه نیاز به استفاده از این قابلیت نداشته باشید ولی باید بدانید این قابلیتی است که در اکثر زبانهای برنامهنویسی شی گرا ارائه نمیشود! |
32 | 32 |
|
33 | | -.. image:: /_static/l19-python-metaclass.png |
| 33 | +.. image:: /_static/l19-python-metaclass-type.jpg |
34 | 34 | :align: center |
35 | | - :target: https://blog.ionelmc.ro/2015/02/09/understanding-python-metaclasses/ |
36 | 35 |
|
37 | 36 | **متاکلاس چیست؟** یک کلاس است و اشیایی که از آن ایجاد میگردند، کلاسها هستند! بارها گفته شد که «هر چیزی در پایتون یک شی است» و این جمله حتی خود موجودیت کلاسها را نیز شامل میشود. با اجرای دستور تعریف کلاس، یک شی از نوع ``type`` در حافظه ایجاد میگردد و از نام کلاس برای اشاره به آن شی استفاده میشود (درس هفدهم). اکنون میتوانیم بگوییم که ``type`` در واقع یک متاکلاس میباشد:: |
38 | 37 |
|
|
101 | 100 |
|
102 | 101 | برای ایجاد متا کلاس تنها کافی است یک کلاس جدید بسازید که از کلاس ``type`` ارثبری داشته باشد. با ارسال نام این کلاس به پارامتر ``metaclass`` هر کلاس دیگری میتوان به آنها انتساب داد. |
103 | 102 |
|
| 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 | + |
104 | 180 | بر اساس تعریف ارائه شده در [`اسناد پایتون <https://docs.python.org/3/glossary.html#term-metaclass>`__]، تعریف کلاس (دستور ``class``) باعث ایجاد «نام کلاس»، «یک شی دیکشنری از کلاس» و «یک شی لیست حاوی superclassهای آن کلاس» میشود، متاکلاس این سه آرگومان را دریافت و شی کلاس را ایجاد میکند. |
105 | 181 |
|
106 | 182 |
|
|
0 commit comments