我需要直接从继承的类更改对象变量。 这是我的代码示例:
class A(object):
def __init__(self,initVal=0):
self.myVal = initVal
def worker(self):
self.incrementor = B()
self.incrementor.incMyVal(5)
class B(A):
def incMyVal(self,incVal):
super().myVal += incVal
obj = A(5)
print(obj.myVal)
obj.worker()
print(obj.myVal)
但它不起作用:
AttributeError: 'super' object has no attribute 'myVal'
我还试图在B类中使用我的变量的全局/非本地关键字,但没有运气。
在我的主要情况中,B
类是一个事件处理程序。它应该在事件触发时更改对象的属性。因此,我无法在return
方法中使用incMyVal
。
答案 0 :(得分:3)
super()
只能在类MRO中搜索类属性,而不能在实例属性中搜索。 myVal
设置在类的实例上,而不是类本身。
只有一个例子;如果来自类A
的代码或派生类正在改变实例上的属性并不重要,那么它只是一个名称空间。
但是,在您的情况下,您甚至不应该使用继承。您正尝试使用独立的第二个实例来更改A
实例的属性。类继承不允许您像这样访问基类的实例。
重构B
以获取A
的实例,然后对该实例执行操作:
class B:
def __init__(self, ainstance):
self.ainstance = ainstance
def incMyVal(self, incVal):
self.ainstance.myVal += incVal
请注意,B
不是此处A
的子类;它根本不是同一类型的(专业)对象;它是一种不同的东西,可以增加另一个对象的属性。
创建B
的实例时传递实例:
def worker(self):
self.incrementor = B(self)
self.incrementor.incMyVal(5)
这确实创建了一个循环引用,它可以使对象保持活动的时间超过可能需要的时间。您可能希望使用weak reference代替:
import weakref
class B:
def __init__(self, ainstance):
self.ainstance_ref = weakref.ref(ainstance)
def incMyVal(self, incVal):
ainstance = self.ainstance_ref()
if ainstance is not None:
ainstance.myVal += incVal
现在B
个实例仅包含对其A
实例的弱引用,如果该实例不再存在,则不执行任何操作。