Python:在子类中更新父类的实例变量。

11 浏览
0 Comments

Python:在子类中更新父类的实例变量。

我在这方面搜索了很多,但似乎找不到与我的问题相关的具体信息。\n假设我有三个独立的Python文件:fileA.py、fileB.py和fileMain.py\nfileB.py继承自fileA.py。\nfileA.py\n

class Parent():
    def __init__(self):
        self.valueA = 5

\nfileB.py\n

from fileA import Parent
class Child(Parent):
    def __init__(self):
        Parent.__init__(self)
        self.valueB = 10
    def Calculate(self):
        self.result = self.valueB + self.valueA
        print(self.result)

\n在fileMain.py中,我有一些代码,在父类中的valueA被更改后,调用Child类中的Calculate方法。\n

from fileA import Parent
from fileB import Child
class MainProgram():
    def __init__(self):
        self.parent = Parent()
        self.child = Child()
        self.parent.valueA = 8
        self.child.Calculate()
foobar = MainProgram()

\n我的问题是,打印输出是15,而不是18。为什么?如何解决这个问题以获得预期的结果?\n我希望fileB.py从fileA.py继承的原因是,我计划在fileC.py中也从fileA.py继承,并在其中进行其他计算,也使用self.valueA。valueA应该由程序的用户设置。我在这里简化了一些事情。希望这能说得通?\n如果我使用术语错误,请纠正我。 🙂

0
0 Comments

问题出现的原因是作者对类和实例的概念理解不清楚。作者错误地认为通过子类调用父类的方法会更新父类的实例变量。

解决方法是要理解类和实例的区别。类是一个蓝图,实例是根据这个蓝图创建的对象。当你实例化一个类时,你得到一个实例。在这个例子中,parent和child就是实例。当你调用parent.valueA = 8时,你实际上是在改变名为parent的实例上的一个值。

当你调用child.Calculate()时,它与parent实例无关。当你实例化Child()时,Parent()的构造函数被调用,所以child.valueA被设置为5。你需要调用child.valueA = 8来改变它。

如果你想要在所有父类实例之间共享父类的状态,可以使用Borg模式。每个Borg实例与所有其他实例共享其状态。所以如果你做parent1 = Parent()和parent2 = Parent(),然后做parent1.valueA = 8,那么parent2.valueA也将等于8。

下面是一个示例代码:

class Parent(object): #This is a Borg class
    __shared_state = {}
    def __init__(self):
        self.__dict__ = self.__shared_state
        self.valueA = 5
class Child(Parent):
    def __init__(self):
        Parent.__init__(self)
        self.valueB = 10
    def Calculate(self):
        self.result = self.valueB + self.valueA
        print(self.result)
class MainProgram():
    def __init__(self):
        self.parent = Parent()
        self.child = Child()
        self.parent.valueA = 8
        self.child.Calculate()
foobar=MainProgram()

感谢启发!如果我有多个类从同一个父类继承valueA,那么我必须为所有的子类分别赋值吗?我希望有一种更高效的方法。

你要找的是Borg模式。我会更新我的回答来展示它是如何工作的。个人而言,我并没有真正使用过它,所以我不能给你一个最好的解释它为什么工作,但它将解决你的问题。以下是一个示例代码和一个有用的讨论链接:

Borg模式示例代码:[github.com/faif/python-patterns/blob/master/creational/borg.py](https://github.com/faif/python-patterns/blob/master/creational/borg.py)

有用的讨论链接:[stackoverflow.com/questions/1318406](https://stackoverflow.com/questions/1318406)

在Python中,一切都是对象,甚至类也是对象。所以有类和它们的实例。但一个对象可以是类,一个实例也可以是类(所有的类都是type的实例,例如)。

是的,从技术上讲这是正确的。但这并不帮助初学者理解发生了什么。在Python之外,对象通常与实例相同(尽管在这一点上有一些争议,主要是当人们指向原始类型时:它们不是任何实例,但它们是对象;个人而言,我更倾向于将它们称为值而不是对象)。无论如何,我只在一处提到了object,但在整个文中都提到了实例。

0