Разница между , ?

#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'>)
>>>