#python #inheritance #diamond-problem
Вопрос:
Я использую (и учусь) Python3 У меня есть высший класс (geometry_0) , определяющий структуру описания геометрии, и его дочерние элементы (геометрия(geometry_0)), которые дают структуру измененной геометрии. Производные классы, например, простая геометрия: парабола(geometry_0) и модифицированный параболо_шифрованный(геометрия,парабола). Геометрия содержит функцию super (), но она ссылается на параболу, а не на geometry_0. Я доволен этим, но не понимаю, почему. Это своего рода структура алмаза, может быть, это может быть позади? Но что происходит во время компиляции?
Упрощенный фиктивный код:
class Geometry_0():
@classmethod
def x2y(cls,geom_pars: dict, x: float) -> float:
print('in Geometry_0')
return NotImplemented
class Geometry(Geometry_0):
@classmethod
def transform(cls,geom_pars: dict, x_child: float) ->float:
return NotImplemented
@classmethod
def x2y(cls,geom_pars: dict, x_child: float):
print('in Geometry')
x_parent = cls.transform(geom_pars,x_child)
return super().x2y(geom_pars,x_parent) # that should refer to geometry_0 ??
class Parabola(Geometry_0): # y = a * x**2
@classmethod
def x2y(cls, geom_pars, x):
print('in Parabola')
a = geom_pars['a']
return a * x**2
class Parabola_shifted(Geometry,Parabola): # y = a * (x-x0)**2
@ classmethod
def transform(cls,geom_pars: dict, x_child: float) ->float:
x0 = geom_pars['x0']
x_parent = x_child - x0
return x_parent
# x2y is inherited from geometry, that calls the super().x2y
print('parabola')
print(Parabola.x2y({'a': 1},2))
print('shifted parabola')
print(Parabola_shifted.x2y({'a':1, 'x0': 2}, 2))
На выходе получается:
parabola at 2: y= 1* 2**2 = 4
in Parabola
4
shifted parabola at 2: y= 1* (2-2)**2 = 0
in Geometry
in Parabola
0
‘
Ответ №1:
Вам нужно понять MRO Python (Порядок разрешения методов).
Вот хороший урок: https://makina-corpus.com/blog/metier/2014/python-tutorial-understanding-python-mro-class-search-path
Для получения более подробной информации вы можете посмотреть следующее: https://www.python.org/download/releases/2.3/mro/
Пример: D расширяет B и C, сами расширяя A.
class A:
def display(self):
print('A')
class B(A):
def display(self):
print('B')
super().display()
class C(A):
def display(self):
print('C')
super().display()
class D(B, C):
def display(self):
print('D')
super().display()
d = D()
d.display()
super
будет следовать за MRO и, в зависимости как от контекста класса, в котором он вызывается, так и от типа экземпляра, он найдет следующий объект в списке приоритетов
выход:
D
B
C
A
Алгоритм начинается с объявленного графика наследования и удаляет дублированные записи, сохраняя только их последнее появление
С предыдущим примером:
D, B, object , C, object ⇒ D, B, C, object
Комментарии:
1. Тогда я прав в следующем?: путь поиска в вашем коде-DBACA. Старый MRO удаляет те же классы, что и раньше, в то время как новый удаляет те же классы, что и раньше, поэтому в python
2. Я думаю, что это DBAC для python
3. Извините, да, DBAC, я просто не могу это исправить