Richard
Richard

Reputation: 123

Issues with creating an app wide config class

I have created two python modules to demonstrate a common problem i seem to have developing python apps.

test_config.py

import do_something

class TestConfig:

  _conf = {
    
    "test_case": 'Goodbye',
  }


  @staticmethod
  def get_config(name):
    return TestConfig._conf[name]

  @staticmethod
  def set(name, value):
      TestConfig._conf[name] = value

if __name__ == "__main__":

    print(TestConfig.get_config('test_case'))   # prints Goodbye
    TestConfig.set('test_case', 'Hello')  
    print(TestConfig.get_config('test_case'))   # Prints Hello
    do_something.say_something()    # prints Goodbye?

    # Why does do_something print Goodbye- expected Hello

do_something.py

from test_config import TestConfig

def say_something():

    text = TestConfig.get_config('test_case')
    print(text)

Could someone explain why do_something.say_something() prints out Goodbye and not Hello? And maybe the best way to create a global config class to access global variables. I keep running into similar problems as well as circular imports. I need to set some config variables at runtime.

Upvotes: 0

Views: 47

Answers (1)

jupiterbjy
jupiterbjy

Reputation: 3503

Let's put this one line:

print(id(TestConfig))

like this:

import do_something


class TestConfig:
    _conf = {

        "test_case": 'Goodbye',
    }

    @staticmethod
    def get_config(name):
        return TestConfig._conf[name]

    @staticmethod
    def set(name, value):
        TestConfig._conf[name] = value


print(id(TestConfig))


if __name__ == "__main__":
    print(TestConfig.get_config('test_case'))  # prints Goodbye
    TestConfig.set('test_case', 'Hello')
    print(TestConfig.get_config('test_case'))  # Prints Hello
    do_something.say_something()  # prints Goodbye?

and this

from test_config import TestConfig

print(id(TestConfig))


def say_something():

    text = TestConfig.get_config('test_case')
    print(text)

We only put 2 lines, so it should print out 2 of same ID right?

1700517329968
1700517329968
1700517331888
Goodbye
Hello
Goodbye

It is in fact called 3 times, and 3rd one actually has different id! So it has different TestConfig.

Logic is:

Main script(test_config.py) imports do_something.py do_something.py imports test_config.py as module! (if __name__ == "__main__": is now false so that block doesn't run)

Honestly I am not 100% sure how this doesn't count as circular import, but maybe import to test_config.py didn't import do_something again because it is already imported in namespace or it has some circular import resolving logic.

Suggested fix is, having a separate configuration python script or json/yaml any data format. This kind of circular import is not a good solution!

Upvotes: 1

Related Questions