Home > database >  Python class inheritance and sharing variables
Python class inheritance and sharing variables

Time:05-28

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.

The problem is, pylint and my IDE say "Instance of 'Base' has no 'settings' member". Which I understand is because it's not initialized in 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()

This is a slightly modified version, where I am passing 'self' from Top twice to Base, and using 'main.settings' instead of self.settings. Pylint nor my IDE complain about this. I'm clearly passing the self instance into it to share, so I understand that.

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.

CodePudding user response:

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

CodePudding user response:

You should create self.settings in the base class, not the child. Then the child can add its key to it after calling the base's __init__() method.

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()

CodePudding user response:

I would pass in **kwargs, so it's easy to keep insertion order the same as you had it:

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
  • Related