В чем основные отличия между метаклассами Python и декораторами класса? Есть ли что-то, что я могу сделать с одним, но не с другим?
Метаклассы Python против декораторов класса
Ответ 1
Декораторы намного, намного проще и более ограничены - и поэтому должны быть предпочтительнее всякий раз, когда желаемый эффект может быть достигнут либо с помощью метакласса, либо с декоратором класса.
Все, что вы можете сделать с помощью декоратора класса, вы, конечно, можете сделать с помощью настраиваемого метакласса (просто примените функциональность "функции декоратора", то есть тот, который принимает объект класса и изменяет его, в ходе метакласс __new__
или __init__
, которые делают объект класса! -).
Есть много вещей, которые вы можете сделать в пользовательском метаклассе, но не в декораторе (если только декоратор не создает и не применяет собственный метакласс, но это мошенничество; -)... и даже тогда, в Python 3, есть вещи, которые вы можете делать только с помощью обычного метакласса, а не после факта... но это довольно продвинутая суб-ниша вашего вопроса, поэтому позвольте мне привести более простые примеры).
Например, предположим, что вы хотите сделать объект класса X
таким, чтобы print X
(или в Python 3 print(X)
, конечно;-) отображает peekaboo!
. Вы не можете сделать это без специального метакласса, потому что переопределение метакласса __str__
является решающим актером здесь, т.е. Вам нужен def __str__(cls): return "peekaboo!"
в пользовательском метаклассе класса X
.
То же самое относится ко всем магическим методам, т.е. ко всем видам операций, которые применяются к самому объекту класса (в отличие от тех, которые применяются к его экземплярам, которые используют магические методы, как определено в классе, - операции на сам объект класса использует магические методы, определенные в метаклассе).