Порядок разрешения метода (MRO) в модернизированных классах?

+1 для Визуального Помогают, И я добавлю VLH (Визуальная Локальная История), который обеспечивает своего рода локальную систему управления исходным кодом. Каждый раз, когда Вы сохранили файл, плагин добавляют копию в локальном репозитории.

85
задан martineau 30 July 2017 в 17:56
поделиться

3 ответа

Ключевое различие между порядком разрешения для устаревших классов и классов нового стиля возникает, когда один и тот же класс-предок встречается более одного раза в "наивном" подходе с ориентацией в глубину - например, рассмотрим " случай наследования алмазов:

>>> class A: x = 'a'
... 
>>> class B(A): pass
... 
>>> class C(A): x = 'c'
... 
>>> class D(B, C): pass
... 
>>> D.x
'a'

здесь, в традиционном стиле, порядок разрешения следующий: D - B - A - C - A: поэтому при поиске Dx, A является первой базой в разрешении, чтобы решить эту проблему, тем самым скрывая определение в C. В то время как:

>>> class A(object): x = 'a'
... 
>>> class B(A): pass
... 
>>> class C(A): x = 'c'
... 
>>> class D(B, C): pass
... 
>>> D.x
'c'
>>> 

здесь, новый стиль, порядок следующий:

>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, 
    <class '__main__.A'>, <type 'object'>)

с A вынужден идти в порядке разрешения только один раз и после всех его подклассов, чтобы переопределить (т. е. Переопределение C элемента x ) действительно работает разумно.

Это одна из причин, по которой следует избегать классов старого стиля: множественное наследование с «ромбовидными» шаблонами просто не работает.т работать с ними разумно, тогда как с новым стилем.

172
ответ дан 24 November 2019 в 08:14
поделиться

Полученный результат верен. Попробуйте изменить базовый класс Base3 на Base1 и сравните с той же иерархией для классических классов:

class Base1(object):
    def amethod(self): print "Base1"

class Base2(Base1):
    pass

class Base3(Base1):
    def amethod(self): print "Base3"

class Derived(Base2,Base3):
    pass

instance = Derived()
instance.amethod()


class Base1:
    def amethod(self): print "Base1"

class Base2(Base1):
    pass

class Base3(Base1):
    def amethod(self): print "Base3"

class Derived(Base2,Base3):
    pass

instance = Derived()
instance.amethod()

Теперь он выводит:

Base3
Base1

Прочтите это объяснение для дополнительная информация.

5
ответ дан 24 November 2019 в 08:14
поделиться

Вы наблюдаете такое поведение, потому что при разрешении метода сначала используется глубина, а не ширина. Наследование Dervied выглядит как

         Base2 -> Base1
        /
Derived - Base3

Итак instance.amethod ()

  1. Проверяет Base2, не находит метод.
  2. Видит, что Base2 унаследовал от Base1, и проверяет Base1. Base1 имеет метод , поэтому он вызывается.

Это отражено в Derived .__ mro __ . Просто переберите Derived .__ mro __ и остановитесь, когда найдете искомый метод.

0
ответ дан 24 November 2019 в 08:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: