1

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.

2
  • If you try to create an instance of Base rather than Top, it will try to use self.settings without ever assigning that variable. Commented May 27, 2022 at 23:37
  • this is technically not best/good practices in python Commented May 27, 2022 at 23:38

3 Answers 3

1

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

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, this makes more sense. You and @Barmar, are correct. For my particular case, I had a number of "base" classes, all pulled into the Top class. They all share 'settings'. I was able to fix it by creating a single "Base" class with self.settings defined, pulling that into my other classes, and finally those other classes into Top class. All of them can share self.settings. Thanks!
1

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

Comments

0

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.