Reputation: 7719
I'm relatively new to Python and would like to know if I'm reinventing a wheel or do things in a non-pythonic way - read wrong.
I'm rewriting some parser originally written in Lua. There is one function which accepts a field name from imported table and its value, does some actions on value and stores it in target dictionary under a appropriate key name.
In the original code it's solved by long switch-like statement with anonymous functions as actions. Python code looks like the following:
class TransformTable:
target_dict = {}
...
def mapfield(self, fieldname, value):
try:
{
'productid': self.fn_prodid,
'name': self.fn_name,
'description': self.fn_desc,
...
}[fieldname](value)
except KeyError:
sys.stderr.write('Unknown key !\n')
def fn_name(val):
validity_check(val)
target_dict['Product'] = val.strip().capitalize()
...
Every "field-handler" function does different actions and stores in different keys in target_dict, of course. Because Python does not support anonymous functions with statements (or did I missed something ?) the functions have to be written separately which does code less readable and unnecessarily complicated.
Any hints how to do such tasks in a more elegant and more pythonic way are appreciated.
Thx
David
Upvotes: 5
Views: 350
Reputation: 123463
I applied an approach similar to @Matti Virkkunen'a a while ago in my answer to a question titled "switch case in python doesn't work; need another pattern". It also demonstrates a relatively easy and graceful way of handling unknown fields. Transliterated to terms in your example it would look like this:
class TransformTable:
target_dict = {}
def productid(self, value):
...
def name(self, value):
validity_check(value)
self.target_dict['Product'] = value.strip().capitalize()
def description(self, value):
...
def _default(self, value):
sys.stderr.write('Unknown key!\n')
def __call__(self, fieldname, value):
getattr(self, fieldname, self._default)(value)
transformtable = TransformTable() # create callable instance
transformtable(fieldname, value) # use it
Upvotes: 0
Reputation: 65126
If by any means possible, you could name your member functions based on the field names and just do something like this:
getattr(self, "fn_" + fieldname)(value)
Edit: And you can use hasattr
to check if the function exists, instead of expecting a KeyError. Or expect an AttributeError. At any rate, you should put only the access inside your try..except
, and call it outside, since otherwise a KeyError caused within one of the field methods could get misunderstood.
Upvotes: 1