Ответ 1
То, что вы ищете, называется "метаклассом"... так же, как a
является экземпляром класса a
, a
является экземпляром класса, также называемым метаклассом. По умолчанию классы Python являются экземплярами класса type
(единственное исключение относится к Python 2, у которого есть некоторые устаревшие классы "старого стиля", которые являются теми, которые не наследуются от object
). Вы можете проверить это, выполнив type(A)
... он должен вернуть type
сам (да, этот объект был перегружен немного).
Метаклассы являются мощными и извращенными мозгами, чтобы заслужить больше, чем быстрое объяснение, которое я собирался написать... хорошей отправной точкой был бы этот вопрос stackoverflow: Что такое Metaclass.
Для вашего конкретного вопроса, для Python 2, создается метаклас, который псевдонимы len(A)
вызывает метод класса в A:
class LengthMetaclass(type):
def __len__(self):
return self.clslength()
class A(object):
__metaclass__ = LengthMetaclass
@classmethod
def clslength(cls):
return 7
print len(A)
Python 3 работает аналогично, но вы использовали бы class A(object, metaclass=LengthMetaclass):
вместо __metaclass__ = LengthMetaclass
.
Причина LengthMetaclass.__len__
не влияет на экземпляры a
, так это то, что разрешение атрибута в Python сначала проверяет экземпляр dict, затем проходит иерархию классов [A, object]
, но он никогда не обращается к метаклассам. Если для доступа к A.__len__
сначала обращается внимание на экземпляр a
, тогда идет его иерархия классов, состоящая из [LengthMetaclass, type]
.