Python class 继承和共享变量

Python class inheritance and sharing variables

我有一个关于访问两个 class 之间的变量的问题,其中一个是基础 class。我有一个正在编写的程序,其中有一个 'settings' 变量,它在多个 class 之间共享。这是它的简化版本。

此代码片段有效。当我 运行 它时,我可以从顶部 class 访问 运行(),并且两个 class 都可以访问 self.settings,当我打印它时从 go() 出来,它包含 'a' 和 'b' 键。

问题是,pylint 和我的 IDE 说“'Base' 的实例没有 'settings' 成员”。我的理解是因为它没有在 Base.init().

中初始化
class Base:
    def __init__(self):
        self.settings["b"] = False

    def run(self):
        print("RUN")


class Top(Base):
    def __init__(self):
        self.settings = dict(a=True)
        Base.__init__(self)

    def go(self):
        print(self.settings)


x = Top()
x.go()
x.run()

这是一个稍微修改过的版本,我将 'self' 从 Top 传递到 Base 两次,并使用 'main.settings' 而不是 self.settings。 Pylint 和我的 IDE 都抱怨这个。我明明是把self实例传进去分享,所以我明白了。

class Base:
    def __init__(self, main):
        main.settings["b"] = False

    def run(self):
        print("RUN")


class Top(Base):
    def __init__(self):
        self.settings = dict(a=True)
        Base.__init__(self, self)

    def go(self):
        print(self.settings)


x = Top()
x.go()
x.run()

我不明白的是,实现这一目标的正确方法是什么?另一种选择当然是传递设置变量本身。但是我有几个变量和可能的方法需要被两个classes使用,所以传递'self'似乎是最好的选择。

您应该在基 class 中创建 self.settings,而不是 child。然后 child 可以在调用基础的 __init__() 方法后将其密钥添加到其中。

class Base:
    def __init__(self):
        self.settings = {"b": False}

    def run(self):
        print("RUN")


class Top(Base):
    def __init__(self):
        super().__init__()
        self.settings['a'] = True

    def go(self):
        print(self.settings)


x = Top()
x.go()
x.run()

Base 中初始化 settings,而不是 Top

class Base:
    def __init__(self):
        self.settings = {}
        self.settings["b"] = False

    def run(self):
        print("RUN")


class Top(Base):
    def __init__(self):
        Base.__init__(self)
        self.settings["a"] = True

    def go(self):
        print(self.settings)

子 classes 应该依赖于他们的父 classes,反之亦然。如果 Base 不初始化 self.settings,那么它依赖于其他一些 as-yet-undefined class 来初始化它(这是一个不好的 dependency/assumption 介绍)。

我会传入 **kwargs,因此很容易保持插入顺序与您的顺序相同:

class Base:
    def __init__(self, **kwargs):
        self.settings = {**kwargs, 'b': False}

    def run(self):
        print("RUN")


class Top(Base):
    def __init__(self):
        super().__init__(a=True)

    def go(self):
        print(self.settings)


x = Top()
x.go()
x.run()

输出:

{'a': True, 'b': False}
RUN