Most Pythonic way to provide global configuration variables in config.py?

How about just using the built-in types like this:

config = {
    "mysql": {
        "user": "root",
        "pass": "secret",
        "tables": {
            "users": "tb_users"
        }
        # etc
    }
}

You'd access the values as follows:

config["mysql"]["tables"]["users"]

If you are willing to sacrifice the potential to compute expressions inside your config tree, you could use YAML and end up with a more readable config file like this:

mysql:
  - user: root
  - pass: secret
  - tables:
    - users: tb_users

and use a library like PyYAML to conventiently parse and access the config file


I like this solution for small applications:

class App:
  __conf = {
    "username": "",
    "password": "",
    "MYSQL_PORT": 3306,
    "MYSQL_DATABASE": 'mydb',
    "MYSQL_DATABASE_TABLES": ['tb_users', 'tb_groups']
  }
  __setters = ["username", "password"]

  @staticmethod
  def config(name):
    return App.__conf[name]

  @staticmethod
  def set(name, value):
    if name in App.__setters:
      App.__conf[name] = value
    else:
      raise NameError("Name not accepted in set() method")

And then usage is:

if __name__ == "__main__":
   # from config import App
   App.config("MYSQL_PORT")     # return 3306
   App.set("username", "hi")    # set new username value
   App.config("username")       # return "hi"
   App.set("MYSQL_PORT", "abc") # this raises NameError

.. you should like it because:

  • uses class variables (no object to pass around/ no singleton required),
  • uses encapsulated built-in types and looks like (is) a method call on App,
  • has control over individual config immutability, mutable globals are the worst kind of globals.
  • promotes conventional and well named access / readability in your source code
  • is a simple class but enforces structured access, an alternative is to use @property, but that requires more variable handling code per item and is object-based.
  • requires minimal changes to add new config items and set its mutability.

--Edit--: For large applications, storing values in a YAML (i.e. properties) file and reading that in as immutable data is a better approach (i.e. blubb/ohaal's answer). For small applications, this solution above is simpler.