събота, 17 януари 2009 г.

Пак Метакласове в Python

„ Програмиране с Python“, ФМИ
Стефан Кънев & Николай Бачийски
16.05.2007г.

[Metaclasses] are deeper magic than 99% of users should ever worry about. If you wonder whether you need them, you don't (the people who actually need them know with certainty that they need them, and don't need an explanation about why).

Tim Peters

Какво е метаклас?


Метаклас — клас, чийто инстанции са класове.


Забравете предишнoto твърдение.
Метапрограмиране

* Meta (from Greek: μετά = "after", "beyond", "with"), is a prefix used in English in order to indicate a concept which is an abstraction from another concept, used to complete or add to the latter.
* Програмиране за програмирането.
* Програмиране, при което клиентите са програмисти.
* При ООП:
o разширяване на езика с нови ”типове класове“
o промяна на природата на обектите
+ добавяне на функционалност (методи от метакласа например)
+ създаване на обекти, които приличат на класове (от които могат да се правят нови инстанции)
+ налагане на ограничения върху класовете
o автоматизиране на сложни задачи
+ регистриране на новосъздадени класове в някаква система

Метакласовете като инструмент за метапрограмиране

* Почти всичко може да се направи и без метакласове:
o factory класове
o функции, които обработват класа след създаването му
o функции, които регистрират новосъздадения клас в системата
* С метакласове просто е по-лесно и по-елегантно
* Използват се вътрешно в типовата система на Python

Употреба: регистрация/търсене

Искаме да видим всички класове, които са се регистрирали в нашата система.

Пример: имаме зоологическа градина с цяла йерархия от класове, като позволяваме на програмистите да дефинират нови класове от животни. Как да видим всички класове животни? Как да видим всичко животни, които могат да плуват? Как да намерим всички животни наследник на класа Риба?
Употреба: проверки при създаване на класове

* Гаранция, че класът удовлетворява определен интерфсейс
* Проверка за стил на кода:
o наличие на docstring-ове
o имена на методи — getName срещу get_name
o дълбочина на наследяването — ≤ 5
* Всякакви други проверки, които ще гарантират, че нмовосъздадения клас отговаря на изискванията на вашата система

Внимавайте да не сте много строги.
Употреба: създаване на специални класове

* обвиване на методи (pre/post conditions)
* добавяне, преименуване на методи
* зареждане на методи/родители от някъде:
o зависещи от системата: разширения (plugins)
o XML схеми и DTD

В Python

* при създаване на тялото на клас се гледа стойността на __metaclass__
* по подразбиране метакласа е type или types.ClassType (стар стил)
* метаклас може да се наследи и от родителски клас

Какво може/трябва да има един метаклас?

* (Мета)класовете са частен случай на обикновени обекти — с техните методи, свойства
* Всичко основно може да се наследи от type и за нас не остава кой знае колко за добавим
* Най-често се променят:
o Инициализатори: __new__, __init__
o Представяне на класовете като низове
o Атрибути и свойства на новия клас (включително методи:)
* Не могат да се ползват за промяна на логиката на:
o търсене в пространсвата от имена
o MRO (Method Resolution Order)
o Дескрипторите (за тях по-нататък)

Няма коментари:

Публикуване на коментар