使用类字典映射到Python中的实例方法

时间:2012-10-16 19:12:56

标签: python dictionary control-flow

我有一个很长的if-elif链,像这样:

class MyClass:
    def my_func(self, item, value):
        if item == "this":
            self.do_this(value)
        elif item == "that":
            self.do_that(value)
        # and so on

我觉得难以阅读,所以我更喜欢使用字典:

class MyClass:
    def my_func(self, item, value):
        do_map = {
            "this" : self.do_this,
            "that" : self.do_that,
            # and so on
        }

        if item in do_map:
            do_map[item](value)

每次调用函数时重新创建映射都很愚蠢。我怎样才能重构这个类,以便为所有实例创建一次字典?我可以以某种方式将do_map转换为类成员,但仍然映射到实例方法吗?

2 个答案:

答案 0 :(得分:5)

您必须使用__init__方法初始化地图:

def __init__(self):
    self.do_map = dict(this=self.do_this, that=self.do_that)

或使用string-and-getattr方法:

class Foo(object):
    do_map = dict(this='do_this', that='do_that')

    def my_func(self, item, value):
        if item in do_map:
            getattr(self, do_map[item])(value)

答案 1 :(得分:1)

我的(未经测试)拍摄,稍加缓存:

class Something(object):
    def __init__(self):
        self.__do_map = {}

    def my_func(self, item, value):
        self.__do_map.setdefault(item, getattr(self, 'do_{}'.format(item)))(value)

OTOH,您可以获取未绑定的方法,然后明确地将self作为第一个实例传递...

class Something(object):
    _do_methods = {}
    def __init__(self:
        pass

    def my_func(self, item, value):
        ubf = Something._do_methods.setdefault(item, getattr(Something, 'do_{}'.format(item)))
        ubf(self, value)

    def do_test(self, value):
        print 'test is', value