【问题标题】:How to change variable of main class from inherited class?如何从继承类更改主类的变量?
【发布时间】:2016-09-13 10:32:21
【问题描述】:

我需要直接从继承的类中更改对象变量。 这是我的代码示例:

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 类是一个事件处理程序。并且它应该在事件触发时更改对象的属性。所以我无法在incMyVal 方法中使用return

【问题讨论】:

  • myVal 不是类属性。它是 instances 上的一个属性,并且实例没有“父”类。
  • @Gnqz:我看不到这里的关系。
  • 你试图做一些非常愚蠢的事情是你做错了。如果您将一个值传递给另一个对象,以便它可以更改您的值您可能只是更改了您自己的值
  • @WayneWerner:这只是一个示例代码。 MartijnPieters 回答说,正是我想要的

标签: python python-3.x


【解决方案1】:

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 实例的弱引用,如果该实例不再存在,则不会执行任何操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-30
    • 2015-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    相关资源
    最近更新 更多