Код, который вы разместили, действительно кажется странным, и использование этого класса само по себе действительно не получится.Например, использование следующего минимального примера:
class SimpleSynchronizationStrategyMixin(object):
def set_messenger(self, messenger):
super(SimpleSynchronizationStrategyMixin,self).set_messenger(messenger)
print('test')
test = SimpleSynchronizationStrategyMixin()
test.set_messenger(None)
выдаст ошибку, как и следовало ожидать:
AttributeError: 'super' object has no attribute 'set_messenger'
Однако, имя класса показывает ответ: itкласс "mixin", класс, который предназначен для смешивания с другим классом .Таким образом, класс добавляет только определенную функциональность и может делать предположения о методах, присутствующих в суперобъекте (который не object
в случае конечного объекта).
Для демонстрациидавайте расширим приведенный выше пример следующим кодом:
class SomeOtherClass(object):
def set_messenger(self, messenger):
print('setting the messenger to %s.' % repr(messenger))
class Demo(SimpleSynchronizationStrategyMixin, SomeOtherClass):
def demo(self):
self.set_messenger('some messenger')
demo = Demo()
demo.demo()
Здесь метод set_messenger
определен в SomeOtherClass
.Класс Demo
затем использует SomeOtherClass
с миксином для создания конечного объекта.Когда вызывается demo()
, он печатает:
setting the messenger to 'some messenger'.
test
Обратите внимание, что порядок суперклассов важен.Если вы напишите class Demo(SomeOtherClass, SimpleSynchronizationStrategyMixin)
, строка «test» не будет напечатана.
Для вашего конкретного примера paxos см. server.py
, который содержит:
class ReplicatedValue(DedicatedMasterStrategyMixin, ExponentialBackoffResolutionStrategyMixin, SimpleSynchronizationStrategyMixin, BaseReplicatedValue):
"""
Mixes the dedicated master, resolution, and synchronization strategies into the base class
""
Здесь вы можетеобратите внимание, что ряд классов mixin «добавлен» в BaseReplicatedValue
для создания ReplicatedValue
.
Обратите внимание, что super()
не всегда возвращает «родительский» объект.Если метод DedicatedMasterStrategyMixin.propose_update(self, ...)
вызывает super(DedicatedMasterStrategyMixin, self).propose_update(...)
, он находит следующий метод propose_update()
в соответствии с Порядком разрешения метода (MRO) .Проще говоря, он просматривает все базовые классы слева направо и возвращает первый найденный метод.Таким образом, каждый метод может вызывать super()
, не зная, какой класс является «родительским», поэтому все необходимые методы могут быть объединены в цепочку.Следующий пример кода демонстрирует это:
class Base(object):
def test(self):
# NB: No super() call in the base class!
print('Test Base')
print('')
class MixinX(object):
def test(self):
print('Test X')
super(MixinX, self).test()
class MixinY(object):
def test(self):
print('Test Y')
super(MixinY, self).test()
class MixinZ(object):
def test(self):
print('Test Z')
super(MixinZ, self).test()
class Final(Base):
pass
class FinalX(MixinX, Base):
pass
class FinalXYZ(MixinX, MixinY, MixinZ, Base):
pass
class FinalZYX(MixinZ, MixinY, MixinX, Base):
pass
class WrongOrder(Base, MixinX, MixinY, MixinZ):
pass
class MixinsOnly(MixinX, MixinY, MixinZ):
pass
"""
>>> Final().test()
Test Base
>>> FinalX().test()
Test X
Test Base
>>> FinalXYZ().test()
Test X
Test Y
Test Z
Test Base
>>> FinalZYX.test()
Test Z
Test Y
Test X
Test Base
>>> WrongOrder().test()
Test Base
>>> MixinsOnly().test()
Test X
Test Y
Test Z
Traceback (most recent call last):
File "superdemo.py", line 36, in <module>
MixinsOnly().test()
File "superdemo.py", line 9, in test
super(MixinX, self).test()
File "superdemo.py", line 14, in test
super(MixinY, self).test()
File "superdemo.py", line 19, in test
super(MixinZ, self).test()
AttributeError: 'super' object has no attribute 'test'
>>> FinalXYZ.mro()
[<class '__main__.FinalXYZ'>, <class '__main__.MixinX'>, <class '__main__.MixinY'>, <class '__main__.MixinZ'>, <class '__main__.Base'>, <type 'object'>]
"""