[Tutor] dictionary dispatch for object instance attributes
question
Jeff Shannon
jeffshannon at gmail.com
Wed Feb 16 03:20:09 CET 2005
On Tue, 15 Feb 2005 17:19:37 -0500, Brian van den Broek
<bvande at po-box.mcgill.ca> wrote:
> My Node class defines a _parse method which separates out the node
> header, and sends those lines to a _parse_metadata method. This is
> where the elif chain occurs -- each line of the metadata starts with a
> tag like "dt=" and I need to recognize each tag and set the
> appropriate Node object attribute, such as .document_type. (I do not
> want to rely on the unhelpful names for the tags in the file format,
> preferring more self-documenting attribute names.)
In addition to using setattr(), I'd take a slightly different approach
to this. (This may just be a matter of personal style, and is not as
clearly advantageous as using setattr() instead of exec, but...)
.class Node(object):
. metadata = {'dt': 'document_type', 'something': 'some_other_field', ...}
. def __init__(self): # ....
. def update(self, **kwargs):
. for key, value in kwargs.items():
. try:
. attr_name = self.metadata[key]
. except KeyError:
. raise ValueError("Invalid field type '%s'" % key)
. setattr(self, attr_name, value)
For starters, I've made metadata a class attribute rather than an
unconnected dictionary. This seems conceptually nicer to me.
In addition, update() can now modify several attributes at once, at
the cost of a bit of extra parsing up front.
Supposing that your node header looks like this:
.header = "dt=text/plain;something=some_value;last=some_other_thing_here"
Now, we can break that into fields, and then split the fields into a
name and a value --
.tags = {}
.for field in header.split(';'):
. name, value = field.split('=')
. tags[name] = value
.
.n = Node()
.n.update(**tags)
You can even simplify this a bit more, by rewriting the __init__():
. def __init__(self, **kwargs):
. if kwargs:
. self.update(**kwargs)
Now you can create and update in a single step:
.n = Node(**tags)
You could also put all of the splitting into fields in a method, and
when __init__ gets a single string as its argument simply pass it to
that method and update with the results...
--Jeff Shannon
More information about the Tutor
mailing list