I’m new to python, and I’ve been reading that using global to pass variables to other functions is considered noobie, as well as a bad practice. I would like to move away from using global variables, but I’m not sure what to do instead.
Right now I have a UI I’ve created in wxPython as its own separate class, and I have another class that loads settings from a .ini file. Since the settings in the UI should match those in the .ini, how do I pass around those values? I could using something like: Settings = Settings() and then define the variables as something like self.settings1, but then I would have to make Settings a global variable to pass it to my UI class (which it wouldn’t be if I assign in it main()).
So what is the correct and pythonic way to pass around these variables?
Edit: Here is the code that I’m working with, and I’m trying to get it to work like Alex Martelli’s example. The following code is saved in Settings.py:
import ConfigParser
class _Settings():
@property
def enableautodownload(self): return self._enableautodownload
def __init__(self):
self.config = ConfigParser.ConfigParser()
self.config.readfp(open('settings.ini'))
self._enableautodownload=self.config.getboolean('DLSettings', 'enableautodownload')
settings = _Settings()
Whenever I try to refer to Settings.settings.enableautodownload from another file I get: AttributeError: 'module' object has no attribute 'settings'. What am I doing wrong?
Edit 2: Never mind about the issue, I retyped the code and it works now, so it must have been a simple spelling or syntax error.
The alternatives to
globalvariables are many — mostly:Each of these (esp. the first and third ones) is particularly useful for values whose names must not be re-bound by all and sundry, but only accessed. The really big problem with
globalis that it provides a “covert communication channel” (not in the cryptographic sense, but in the literal one: apparently separate functions can actually be depending on each other, influencing each other, via global values that are not “obvious” from the functions’ signatures — this makes the code hard to test, debug, maintain, and understand).For your specific problem, if you never use the
globalstatement, but rather access the settings in a “read-only” way from everywhere (and you can ensure that more fully by making said object’s attributes be read-only properties!), then having the “read-only” accesses be performed on a single, made-once-then-not-changed, module-level instance, is not too bad. I.e., in some modulefoo.py:and from everywhere else,
import foothen just accessfoo.settings.oneandfoo.settings.twoas needed. Note that I’ve named the class with a single leading underscore (just like the two instance attributes that underlie the read-only properties) to suggest that it’s not meant to be used from “outside” the module — only thesettingsobject is supposed to be (there’s no enforcement — but any user violating such requested privacy is most obviously the only party responsible for whatever mayhem may ensue;-).