简体   繁体   English

Python 类继承和共享变量

[英]Python class inheritance and sharing variables

I have a question about accessing a variable between two classes, where one is the base class.我有一个关于访问两个类之间的变量的问题,其中一个是基类。 I have a program which I'm writing where there's a single 'settings' variable and it's shared between several classes.我有一个我正在编写的程序,其中有一个“设置”变量,它在几个类之间共享。 This is a simplistic version of it.这是它的简化版本。

This code snippet works.此代码段有效。 When I run it, I can access run() from the Top class, and both classes have access to self.settings, and when I print it out from go(), it contains both 'a' and 'b' keys.当我运行它时,我可以从 Top 类访问 run(),并且两个类都可以访问 self.settings,当我从 go() 打印出来时,它包含“a”和“b”键。

The problem is, pylint and my IDE say "Instance of 'Base' has no 'settings' member".问题是,pylint 和我的 IDE 说“'Base' 的实例没有'settings' 成员”。 Which I understand is because it's not initialized in Base.我的理解是因为它没有在 Base.xml 中初始化。 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()

This is a slightly modified version, where I am passing 'self' from Top twice to Base, and using 'main.settings' instead of self.settings.这是一个稍作修改的版本,我将两次从 Top 传递到 Base 的“self”,并使用“main.settings”而不是 self.settings。 Pylint nor my IDE complain about this. Pylint 和我的 IDE 都对此抱怨。 I'm clearly passing the self instance into it to share, so I understand that.我显然将 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()

What I don't understand, is what is the proper way to achieve this?我不明白,实现这一目标的正确方法是什么? The other option of course is to pass the settings variable itself.另一个选择当然是传递设置变量本身。 However I have several variables and possibly methods which need to be used by both classes, so passing 'self' seems like the best option.但是,我有几个变量和可能的方法都需要由两个类使用,因此传递“自我”似乎是最好的选择。

You should create self.settings in the base class, not the child.您应该在基类而不是子类中创建self.settings Then the child can add its key to it after calling the base's __init__() method.然后孩子可以在调用基础的__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()

Init settings in Base , not Top .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)

Child classes should depend on their parent classes, not vice versa.子类应该依赖于它们的父类,反之亦然。 If Base doesn't init self.settings , then it depends on some other as-yet-undefined class to init it (which is a bad dependency/assumption to introduce).如果Base没有初始化self.settings ,那么它依赖于其他一些尚未定义的类来初始化它(这是一个不好的依赖/假设引入)。

I would pass in **kwargs , so it's easy to keep insertion order the same as you had it:我会传入**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()

Output:输出:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM