Using dictionaries
Alex Martelli
aleaxit at yahoo.com
Tue Dec 5 03:17:12 EST 2000
More information about the Python-list mailing list
Tue Dec 5 03:17:12 EST 2000
- Previous message (by thread): Using dictionaries
- Next message (by thread): Using dictionaries
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
"sorular" <sorular at netscape.net> wrote in message news:3a2c9264.503856587 at news-server.bigpond.net.au... > G'day > > I am trying to write a python program where a "configuration.py" will > have all the user entered values in a dictionary format and a > "main.py" which will import these and use it as local parameters. > > But, there are quite a few values in the dictionary > ie > dict = { 'key1':'value1' , ' key2':'value2' , ......'keyN':'value2'} So far, so good. Some of the values could also be added with a dict['otherkey']='othervalue' syntax, of course. When you "import configuration", both the dict's original definition and the further additions/changes will be executed in order, so we can assume that right after that configuration.dict has all of the settings you require. > and in the "main.py" these will be all renamed with the local names > ie > Val1 = dictionary.dict['key1'] > Val2 = dictionary.dict['key2'] > .... > ValN = dictionary.dict['keyN'] > etc.... First, I assume you mean configuration.dict, unless for some peculiar reason you've chosen to "import configuration as dictionary" (but why would you do that?). > But overall, I still have a large numbe of values (ValN) to list... ! What is the relationship, if any, between the names of the variables such as Val2 and the names of the keys such as key2? If there is no systematic relationship, then you do have to list the whole correspondence one way or another, of course; and the long series of assignments is one such way (or you could have another dictionary, or list or tuple of pairs, etc, etc, and iterate over that). If the correspondence is systematic, such as the one that appears to be implicit in the naming you have used above (each key is named 'key'+suffix for some string suffix, and the variable that must be set like that is named 'Val'+suffix), then you have a much easier life, e.g: for keyname, keyvalue in configuration.dict.items(): if keyname.startswith('key'): __dict__['Val'+keyname[3:]] = keyvalue It's up to you what you want to do (if anything) with dictionary keys that do NOT start with 'key' -- just ignore them, print a warning, throw an exception, whatever. > Q1- Is there a more efficient way to do this ? I thought about using a > for loop but that didnt work.... The above for-loop will certainly work if the relationship between keynames and variable names is as I posit it. If it's otherwise, the only difference is on how you compute the variablename to be set in correspondence to a given key. > Q2 - would it be possible only to list the parameters in first file > (ie dictionary.py > key1 = value1 > key2 = value2 > ..... > keyN = valueN > ) Sure (but is it configuration.py as you said at the start, which would seem a much better name, or dictionary.py as you say now and would seem to imply by your other usages?) -- this way, you're setting up the configuration.__dict__ (or dictionary.__dict__, whatever) dictionary. I.e., if your module is this way, you can use the same loop as above, just change the for-statement itself to: for keyname, keyvalue in configuration.__dict__.items(): # body does not have to change! > and inside main.py, do a simple import... > import dictionary * > so that key1 can be used inside main.py as a local parameter? Local variables are another issue, but I think you mean "module-global" here anyway. Sure, if the correspondence between keyname and variablename is simple identity, this will also work. But a renaming is often advisable, just to avoid accidental clashes (where the user, editing configuration.py, happens by mistake to set a variable whose name equals some other identifier used in main.py), and it's not much harder to perform (as long as it's in some way _systematic_, not haphazard) than just sucking everything in. If you've not decided on a naming convention for keys in configuration.py versus variables in main.py, I suggest you choose a prefix (and ensure no other identifiers in main.py start with that prefix), such as, say, conf_, and do something like: for keyname, keyvalue in configuration.__dict__.items(): if not keyname.startswith(prefix): keyname = prefix+keyname __dict__[keyname] = keyvalue This lets the user write lines in configuration.py such as: foo = 'bar' # sets conf_foo for main.py conf_fee = 'fie' # sets conf_fee ditto and it's _almost_ equivalent to import configuration as conf then using conf.foo, conf.fee, etc, instead of the suggested conf_foo, conf_fee, etc; but it makes it slightly easier to provide defaults in main.py for configuration variables that the user has not set otherwise in configuration.py, i.e. main.py could start with something like: conf_foo = 'a default for conf_foo' conf_fee = 'another important default' conf_fie = conf_fum = conf_bar = None # common default import configuration # insert loop as above then use the various conf_fie, conf_fee, etc etc, as desired; they'd have their default values as set before the import unless the user overrode them in configuration.py. If you'd rather use the conf.foo, conf.fee, etc, syntax for this same purpose (and it would be highly advisable in many ways most of the time), it's also very easy to do so, for example: class conf: foo = 'a default for conf.foo' fee = 'another important default' fie = fum = bar = None # common default from configuration import * assuming configuration.py only uses the plain name and not conf_whatever. Or, the class might also easily use a finer degree of control with an "import configuration", then a loop like the above-exemplified ones. Or you could use an instance object rather than a class object, supposing for example you need ALL conf.whatever variable to be None unless explicitly set, the easiest way might be: class Conf: foo = 'a default for conf.foo' fee = 'another important default' from configuration import * def __getattr__(self, name): return None conf = Conf() Now conf.foo and conf.fee are set by default as above but can be overridden by lines such as "foo = 'something else'" in configuration.py, while ANY other conf.whatever is None unless set in configuration.py. As you can see, Python offers a lot of similar but not identical approaches for the task you've set yourself. It's not part of the party line, but, in Python, too, there's more than one way to do it. How to choose? A golden rule of programming is...: *Do the simplest thing that could possibly work* Being aware of the nicest exotic possibilities is cool, but don't use them unless the defects in SIMPLER ways are actually giving you problems. In other words, from configuration import * might be the best solution (because it's simplest), unless accidental name-clashes ARE actually a problem you need to address, etc, etc. (IMHO, the second simplest approach is that of making conf a class object, as above; the third-simplest, if a "default default value" is actually useful in many cases, is making conf an instance object, again as above; the various loops explicitly manipulating __dict__ I see as a little bit less simple, thus I would not tend to use them in most cases -- unless I get convinced that some simpler approach "can't possibly work" under the specific conditions of a given problem). Alex
- Previous message (by thread): Using dictionaries
- Next message (by thread): Using dictionaries
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Python-list mailing list