Using a class dictionary to map instance methods in Python

I have a long if-elif chain, for example:

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 

It’s hard for me to read, so I prefer to use a dictionary:

 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) 

It is foolish to recreate a map every time a function is called. How can I reorganize this class so that the dictionary is created only once for all instances? Can I somehow turn do_map into a class member, but still map instance methods?

+4
source share
2 answers

You will need to initialize the map in the __init__ method:

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

or use the string-and-getattr method:

 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) 
+5
source

My (untested) accepts with a little caching:

 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, you can get unrelated methods, and then explicitly pass yourself as the first instance ...

 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 
+1
source

Source: https://habr.com/ru/post/1440122/


All Articles