基于字典的带有操作的开关语句

我相对于 Python 还比较陌生,想知道我是否在重复发明轮子,或者是否以非 Pythonic 的方式处理问题,但是我错了。

我正在重写一些最初用 Lua 编写的解析器。有一个函数接受来自导入表的字段名称及其值,对该值执行某些操作,然后将其存储在目标字典中的适当键名下。

在原始代码中,使用类似长switch语句的形式使用匿名函数作为操作执行该函数。 Python 代码如下:

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

当然,每个“字段处理程序”函数执行不同的操作并存储在目标_dict 的不同键中。 因为 Python 不支持带语句的匿名函数(或者是我的理解不到位?),所以这些函数必须单独编写,这会使代码不易读并且复杂化了。

如果有更优雅和 Pythonic 的方式来完成这些任务,请提供一些提示。

谢谢

大卫

原文链接 https://stackoverflow.com/questions/3982533

点赞
stackoverflow用户227267
stackoverflow用户227267

如果可能的话,您可以根据字段名称命名成员函数并像这样做:

getattr(self, "fn_" + fieldname)(value)

编辑:您可以使用 hasattr 检查函数是否存在,而不是期望 KeyError。或者期望 AttributeError。无论如何,您应该只将访问放在您的 try..except 中,并在外部调用它,因为否则在一个字段方法中引发的 KeyError 可能会产生误解。

2010-10-20 21:43:01
stackoverflow用户355230
stackoverflow用户355230

我前段时间在回答一个名为"Python中的_switch case不工作,需要另一个模式"的问题时,采用了类似@Matti Virkkunen的方法。它还演示了如何相对简单和优雅地处理未知字段。转换成您示例中的术语,它将如下所示:

class TransformTable:
    target_dict = {}

    def productid(self, value):
        ...
    def name(self, value):
        检查有效性(value)
        self.target_dict['Product'] = value.strip().capitalize()
    def description(self, value):
        ...

    def _default(self, value):
        sys.stderr.write('未知键!\n')

    def __call__(self, fieldname, value):
        getattr(self, fieldname, self._default)(value)

transformtable = TransformTable() # 创建可调用实例

transformtable(fieldname, value) # 使用它
2010-10-21 07:43:31