I\'m working on a relatively large Python application, and there are several resources that I would like to keep as global variables accessible throughout several different
I think there are two main (ha ha) reasons one might prescribe an avoidance of this pattern.
If you have total control over the application and there will never be another entry point or another use for your features, and you're sure you don't mind the ambiguity, I don't think there's any objective reason why the from __main__ import foo
pattern is bad. I don't like it personally, but again, it's basically for the two reasons above.
I think a more robust/developer-friendly solution may be something like this, creating a special module specifically for holding these super-global variables. You can then import the module and refer to module.VAR
anytime you need the setting. Essentially, just creating a special module namespace in which to store super-global runtime configuration.
# conf.py (for example)
# This module holds all the "super-global" stuff.
def init(args):
global DEBUG
DEBUG = '--debug' in args
# set up other global vars here.
You would then use it more like this:
# main.py
import conf
import app
if __name__ == '__main__':
import sys
conf.init(sys.argv[1:])
app.run()
# app.py
import conf
def run():
if conf.DEBUG:
print('debug is on')
Note the use of conf.DEBUG
rather than from conf import DEBUG
. This construction means that you can alter the variable during the life of the program, and have that change reflected elsewhere (assuming a single thread/process, obviously).
Another upside is that this is a fairly common pattern, so other developers will readily recognize it. It's easily comparable to the settings.py
file used by various popular apps (e.g. django
), though I avoided that particular name because settings.py
is conventionally a bunch of static objects, not a namespace for runtime parameters. Other good names for the configuration namespace module described above might be runtime
or params
, for example.
Doing so requires violating PEP8, which specifies
Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.
In order for gui.py
to successfully import __main__.DEBUG
, you would have to set the value of DEBUG
before import gui
.