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

python – 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
    }
}

Youd 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/ohaals answer).
For small applications, this solution above is simpler.

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

How about using classes?

# config.py
class MYSQL:
    PORT = 3306
    DATABASE = mydb
    DATABASE_TABLES = [tb_users, tb_groups]

# main.py
from config import MYSQL

print(MYSQL.PORT) # 3306

Leave a Reply

Your email address will not be published. Required fields are marked *