2016-05-14 7 views
1

Почему мета-класс не отображается в MRO?Порядок разрешения и метаданные для метода

Например:

>>> class Foo(type): 
... foo = 21 
... 
>>> class Bar(metaclass=Foo): 
... pass 
... 
>>> Bar.mro() 
[<class '__main__.Bar'>, <class 'object'>] 
>>> Bar.foo 
21 

Кроме того, я увидел в другом месте, что Python использует C3 линеаризацию для вычисления MRO, но эта линеаризация не обрабатывает метаклассами. Итак, какой алгоритм использует Python в этом случае?

+1

Вы попробовали позвонить ему на экземпляр бара? Потому что тогда это не сработает. И метаклассы AFAIK и множественное наследование не поддерживаются. Тем не менее, я нахожусь в недоумении, как добраться до Foo на данный момент. – deets

ответ

4

Потому что ни один из ваших классов не получил из метакласса. Метакласс не базовый класс. Метакласс - это завод, который создал объект класса Bar, как и объект класса, который создает экземпляры.

Здесь не требуется линеаризация. Bar - объект типа Foo, как и другие классы имеют тип type. Любые подклассы Bar будут иметь один и тот же тип (метакласс); они имеют это отношение напрямую. Класс может иметь только один метакласс за раз.

Метакласс приходит последним при поиске атрибутов; так что Bar.spam сначала нужно искать в MRO, и только затем на type(Bar).

Конечно, метаклассы также используют иерархию наследования; Foo был получен из type в вашем примере. Эти отношения также используют MRO.

+0

Спасибо. Как насчет моего второго вопроса? –

+0

@ValentinLorentz: Я думаю, что это уже ответили? –

+0

Извините, я понял сразу после публикации комментария. Кроме того, ваше редактирование также отвечает на это. –

Смежные вопросы