我正在阅读源代码,该源代码阻碍了Python 2.7的paxos算法。在代码中,有许多方法调用超类的方法,而在超类中完全没有此方法,并且这两个方法的名称始终相同。这是Python的特殊功能吗? 例如。超级(SimpleSynchronizationStrategyMixin,self).set_messenger(messenger) SimpleSynchronizationStrategyMixin的超类是不包含方法“ set_messenger”的对象。这行代码所属的方法的确切名称也是“ set_messenger”
class SimpleSynchronizationStrategyMixin(object):
sync_delay = 10.0
def set_messenger(self, messenger):
super(SimpleSynchronizationStrategyMixin,self).set_messenger(messenger)
def sync():
self.messenger.send_sync_request(random.choice(self.peers), self.instance_number)
self.sync_task = task.LoopingCall(sync)
self.sync_task.start(self.sync_delay)
def receive_sync_request(self, from_uid, instance_number):
if instance_number < self.instance_number:
self.messenger.send_catchup(from_uid, self.instance_number, self.current_value)
def receive_catchup(self, from_uid, instance_number, current_value):
if instance_number > self.instance_number:
print 'SYNCHRONIZED: ', instance_number, current_value
self.advance_instance(instance_number, current_value, catchup=True)
答案 0 :(得分:1)
您发布的代码确实确实很奇怪,并且单独使用该类确实会失败。例如,使用下面的最小示例:
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'
但是,该类的名称揭示了答案:它是一个“ 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
与mixin一起使用来创建最终对象。调用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(...)
,它将根据Method Resolution Order (MRO)找到下一个propose_update()
方法。简而言之,它在所有基类中从左到右查找,并返回找到的第一个方法。这样,每个方法都可以调用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'>]
"""