Ful*_*son 3 python inheritance overriding
我试图弄清楚为什么以下示例不起作用。
class BaseClass(object):
def __init__(self):
self.count = 1
def __iter__(self):
return self
def next(self):
if self.count:
self.count -= 1
return self
else:
raise StopIteration
class DerivedNO(BaseClass):
pass
class DerivedO(BaseClass):
def __init__(self):
self.new_count = 2
self.next = self.new_next
def new_next(self):
if self.new_count:
self.new_count -= 1
return None
else:
raise StopIteration
x = DerivedNO()
y = DerivedO()
print x
print list(x)
print y
print list(y)
Run Code Online (Sandbox Code Playgroud)
这是输出:
<__main__.DerivedNO object at 0x7fb2af7d1c90>
[<__main__.DerivedNO object at 0x7fb2af7d1c90>]
<__main__.DerivedO object at 0x7fb2af7d1d10>
Traceback (most recent call last):
File "playground.py", line 41, in <module>
print list(y)
File "playground.py", line 11, in next
if self.count:
AttributeError: 'DerivedO' object has no attribute 'count'
Run Code Online (Sandbox Code Playgroud)
如您所见,DerivedO当我尝试在中分配next()方法时,新方法将不会被覆盖__init__。这是为什么?一个简单的next调用可以很好地工作,但是在使用迭代技术时根本无法工作。
编辑:我意识到我的问题还不完全清楚。AttributeError不是我要解决的问题。但是它的确显示了next()被调用BaseClass而不是DerivedO像我想象的那样被调用。
您既不能在实例上__iter__(self)进行扩展,也不能next(self)在实例上进行扩展,因为这些方法被视为类方法,而不是CPython内部优化方法(有关为什么这样做的详细信息,请参阅针对新样式类的特殊方法查找)。
如果需要对这些方法进行monkeypatch,则需要直接在类上设置它们:
class DerivedO(BaseClass):
def __init__(self):
self.new_count = 2
self.__class__.next = self.__class__.new_next
def new_next(self):
if self.new_count:
self.new_count -= 1
return None
else:
raise StopIteration
Run Code Online (Sandbox Code Playgroud)
以上工作;请注意,我设置__class__.next为unbound函数new_next,而不是绑定方法。