[Tutor] dictionary dispatch for object instance attributes question

Brian van den Broek bvande at po-box.mcgill.ca
Tue Feb 15 23:19:37 CET 2005


Hi all,

I'm still plugging away at my project of writing code to process 
treepad files. (This was the task which I posted about in the recent 
"help with refactoring needed -- which approach is more	Pythonic?" 
thread.)

My present problem is how best to reorganize a long (20 elements) elif 
chain. The file format I am dealing with organizes itself with a file 
header, and then a series of nodes. Each node has a header filled with 
up to 20 different metadata elements, followed by the node content 
proper. These metadata elements can be in arbitrary order, and need 
not all be present.

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.)

I've come up with *a* way to use a dictionary dispatch, but I'll wager 
a great deal it isn't the *best* way.

Here is a minimal illustration of what I have come up with:

<code>
class A:

     def __init__(self):

	self.something = None
	self.something_else = None
	self.still_another_thing = None
	
     def update(self, data):

	for key in metadata_dict:
	    if data.startswith(key):
                 exec('''self.%s = """%s"""''' %(metadata_dict[key],
                      data[len(key):]))
		# triple quotes as there may be quotes in metadata
                 # values
		break

metadata_dict = {'something_tag=': 'something',
                  '2nd_tag=': 'something_else',
                  'last=': 'still_another_thing'}

a = A()
print a.still_another_thing
a.update('last=the metadata value for the "last=" metadata tag')
print a.still_another_thing
</code>

<output>
 >>>
None
the metadata value for the "last=" metadata tag
</output>

So, it works. Yay :-)

But, should I be doing it another way?

Also, I know the general security concerns about things like exec. 
They make me nervous in using it, even though I am (as yet) the sole 
user. Am I right in thinking that the constrained way I am using it 
here protects me? My code uses most of the attributes as a simple 
storage container for later rewriting of the file, but in a few cases 
they enter into (safe seeming) conditionals like:

if 'text' == self.document_type:
    self.do_text_stuff()
if 'RTF' == self.document_type:
    self.do_RTF_stuff()

Thanks and best to all,

Brian vdB



More information about the Tutor mailing list