Есть ли веская причина вызывать type.mro()
вместо того, чтобы напрямую перебирать type.__mro__
? Доступ буквально в ~13 раз быстрее (36 нс против 488 нс).
Я наткнулся на него, когда искал кэш type.mro()
. Это кажется законным, но это заставляет меня задуматься: могу ли я положиться на type.__mro__
или мне нужно позвонить type.mro()
? и при каких условиях я могу обойтись без первого?
Что еще более важно, какой набор условий должен произойти, чтобы type.__mro__
стало недействительным?
Например, когда определяется/создается новый подкласс, который изменяет mro существующего класса, немедленно ли обновляется существующий класс .__mro__
? Это происходит при каждом создании нового класса? что делает его частью типа класса? Какая часть? ..или об этом type.mro()
?
Конечно, все это предполагает, что type.__mro__
на самом деле является кортежем кэшированных имен, указывающих на объекты в mro данного типа. Если это предположение неверно; тогда что это? (вероятно, дескриптор или что-то в этом роде..) и почему я могу/не могу его использовать?
РЕДАКТИРОВАТЬ: Если это дескриптор, то я хотел бы изучить его магию, так как оба: type(type.__mro__) is tuple
и type(type(type).__mro__) is tuple
(то есть: вероятно, не дескриптор)
EDIT: не уверен, насколько это актуально, но type('whatever').mro()
возвращает список, тогда как type('whatever').__mro__
возвращает кортеж. (Не?) К счастью, добавление к этому списку не меняет __mro__
или последующие вызовы .mro()
из/для рассматриваемого типа (в данном случае str).
Спасибо за помощь!