Метаклассы незаменимы, если вы хотите, чтобы объекты класса (в отличие от экземпляров объектов класса) имели «специальное настраиваемое поведение», поскольку поведение объекта зависит от специальных методов типа . объекта, а тип объекта класса является в точности синонимом метакласса.
Например, если вы хотите, чтобы объект класса X был таким, чтобы «print X» испускал », то Time is now 8: 46am "(в 8:46 или, в более общем смысле, текущее время) это должно означать, что type(x)
(метакласс AKA X) имеет специальный пользовательский метод __str__
- и аналогично (с различными применимыми специальнымиметоды), если вы хотите придать смысл выражениям, таким как X + Y
, где X и Y оба являются объектами класса, или X[23]
(где X, опять же, объект класса) и т. д.
Большинство других задач по настройке теперь (в Python 2.6 или выше) легче реализовать с помощью декоратора классов, который может изменять объект класса сразу после окончания оператора class
.Есть еще несколько случаев, когда это невозможно, потому что изменения должны быть сделаны очень рано, чтобы иметь какой-либо эффект (например, установка или изменение __slots__
).
В Python 3 усиление метаклассовЕще одна полезная деталь: метакласс теперь может опционально указывать объект сопоставления, который будет заполнен во время выполнения тела оператора class
(по умолчанию это обычный dict
).Это позволяет сохранять и использовать порядок привязок имен в теле класса (в то время как нормальный dict
теряет порядок), что иногда хорошо, когда класс должен иметь «поля» в определенном конкретном порядке(например, чтобы отобразить 1: 1 в C struct
, строку в файле CSV или в таблице БД и т. п.) - в Python 2. * это должно быть указано избыточно (обычно с дополнительным атрибутом класса, который являетсяпоследовательность и, следовательно, сохраняет порядок), и эта особенность метаклассов Python 3 позволяет удалить избыточность.