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_prod开发者_如何学Goid,
'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
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.
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
精彩评论