#python #python-2.7
#python #python-2.7
Вопрос:
Согласно здесь:
__mro__
Атрибут типа перечисляет порядок поиска разрешения метода, используемый обоимиgetattr()
иsuper()
. Атрибут является динамическим и может меняться всякий раз, когда обновляется иерархия наследования.
Я попробовал __mro__
атрибут с этим:
class a:
def __init__(self):
self.testValue = 123
Затем я набрал:
type(a).__mro__
(<type 'classobj'>, <type 'object'>)
В чем classobj
дело? И в чем его отличие от object
?
ДОБАВИТЬ 1
Может быть, у меня сегодня немного кружится голова… Но я предполагаю, что это classobj
просто означает class a
, верно? Итак, в приведенном выше выводе просто указано, что порядок разрешения метода является первым, class a
затем type object
.
Комментарии:
1. В Python 2.7 типом ссылки на класс, который не наследуется от
object
, является типclassobj
. Пример:class A:pass; print(type(A))
дает<type 'classobj'>
Ответ №1:
Сначала обратите внимание, что в Python 2.x синтаксис:
class XXX:
# whatever
приведет к классу «старого стиля». Вы можете прочитать больше о классах «старого стиля» и «нового стиля» в the fine manual, на этой странице документа и в Python wiki
Тогда, в вашем случае, вы запрашиваете не mro класса a
, а mro типа class a
(который type(a)
возвращает), в данном случае classobj
типа. Но вам не стоит беспокоиться о классах старого стиля classobj
и т.д., Если вам не нужно поддерживать устаревший код или иметь с ним дело. Для справки, большинство стандартных функций OO Python (включая super()
, дескрипторы и т.д.) Не будут работать должным образом на классах старого стиля, поэтому не используйте их и не пытайтесь понять материал, относящийся к «новой» (ну, примерно 10-летней давности на данный момент ) объектной модели, использующей классы старого стиля…
TL; DR: вы хотите:
class A(object):
# this is a new-style class
Может быть, у меня сегодня немного кружится голова… Но я предполагаю, что classobj просто означает класс a, верно?
Неправильно. classobj
это своего рода особый тип, который служит метаклассом для классов старого стиля. Метакласс, являющийся классом класса (поскольку классы являются объектами, они являются экземплярами класса).
Итак, приведенный выше вывод просто говорит, что порядок разрешения метода — это сначала класс a, затем тип object .
Нет, здесь говорится, что mro для classobj
типа является первым, classobj
затем object
.
Если вам нужен mro класса a
, просто попросите об этом — и тогда вы узнаете, почему вам не следует оценивать функции нового стиля в классах старого стиля:
>>> class a: pass
...
>>> a.__mro__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: class a has no attribute '__mro__'
Теперь сравните с классом нового стиля:
>>> class Foo(object): pass
...
>>> Foo.__mro__
(<class '__main__.Foo'>, <type 'object'>)
>>>