Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 1, 2011 21:29:09

pyOut
От:
Зарегистрирован: 2006-07-16
Сообщения: 125
Репутация: +  0  -
Профиль   Отправить e-mail  

Порядок разрешения методов

По следам уже старой статьи на хабре http://habrahabr.ru/blogs/python/62203/ хотел бы для себя прояснить некоторые моменты, в которых не получилось разобраться.

Версия Python 2.6. В статье пишется что после версии 2.2 Проблема должна возникнуть в ромбовитой структуре.

...class A(object):
... def __init__(self):
... print "A"
...
>>> class B(object):
... def __init__(self):
... print "B"
...
>>> class C(A, B):
... pass
...
>>> C.__mro__
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>)
но у меня как видите линеаризации получилась не такой как предполагалось, т.е. я не вижу проблемы ромбовитой структуры

т.е. C - > A - > object -> B

почему? Или я не правильно понял статью?



Отредактировано (Авг. 1, 2011 21:34:11)

Офлайн

#2 Авг. 2, 2011 00:50:41

bw
От:
Зарегистрирован: 2007-09-26
Сообщения: 938
Репутация: +  20  -
Профиль   Адрес электронной почты  

Порядок разрешения методов

В данном случае, в A должен быть super, хотя я вопроса не понял.

..bw



Офлайн

#3 Авг. 2, 2011 10:21:11

pyOut
От:
Зарегистрирован: 2006-07-16
Сообщения: 125
Репутация: +  0  -
Профиль   Отправить e-mail  

Порядок разрешения методов

Имеется в виду проблема:

Если у нас есть классы A и B, от которых наследуется класс C, то при поиске метода по старому алгоритму (C, A, object, B) получается, что если метод не определён в классах C и A он будет извлечён из object, даже если он определён в B. Это создаёт определённые неудобства, т.к. в object определены многие магические методы, типа __init__, __str__ и т.п. Но даже если object заменить на некий пользовательский класс D, то проблема останется — менее специфичный метод класса-предка может отработать вместо более специфичного метода класса-потомка.
Даже если использовать super все равно mro ставит object в самый конец линеаризации, а не как описано (C, A, object, B)
>>> class A(object):
... def __init__(self):
... print "A"
... super(A, self).__init__()
...
>>> class B(object):
... def __init__(self):
... print "B"
... super(B, self).__init__()
...
>>> class C(A,B):
... pass
...
>>> c = C()
A
B
>>> C.mro()
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>]



Отредактировано (Авг. 2, 2011 10:22:37)

Офлайн

#4 Авг. 2, 2011 12:03:00

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Порядок разрешения методов

Если наследуетесь от object — используется новый алгоритм. Увидеть (C, A, object, B) — нет шансов. У старого, кстати, __mro__ нет совсем.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version