Most Pythonic way to provide global configuration variables in config.py? [closed]
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.
How about using classes?
# config.pyclass MYSQL: PORT = 3306 DATABASE = 'mydb' DATABASE_TABLES = ['tb_users', 'tb_groups']# main.pyfrom config import MYSQLprint(MYSQL.PORT) # 3306