5

I want to create an object of a class based on value of a field.

For eg:

if r_type == 'abc':
                return Abc()
            elif r_type == 'def':
                return Def()
            elif r_type == 'ghi':
                return Ghi()
            elif r_type == 'jkl':
                return Jkl()

What is a pythonic way to avoid if else here. I was thinking to create a dictionary with r_type being key and classname being value, and do a get of the value and instantiate, is it a proper way, or there is something better idiomatic way in python?

U13-Forward
  • 69,221
  • 14
  • 89
  • 114
inquisitive
  • 3,738
  • 6
  • 30
  • 56

3 Answers3

7

You can take advantage of the fact that classes are first class objects in python, and use a dictionary to access the classes you want to create:

classes = {'abc': Abc,    # note: you store the object here
           'def': Def,    #       do not add the calling parenthesis
           'ghi': Ghi,
           'jkl': Jkl}

then create the class like this:

new_class = classes[r_type]()  # note: add parenthesis to call the object retreived

If your classes require parameters, you can place them like in normal class creation:

new_class = classes[r_type](*args, *kwargs)
Reblochon Masque
  • 35,405
  • 10
  • 55
  • 80
3

Or dict.get(..) (thanks for the edit Eran Moshe):

classes = {'abc': Abc,
           'def': Def,
           'ghi': Ghi,
           'jkl': Jkl}


new_class = classes.get(r_type, lambda: 'Invalid input')()
U13-Forward
  • 69,221
  • 14
  • 89
  • 114
2

Best way to this use dict, because complexity of list key operation is constant, it will handle dynamic operation as well.

cf = {
    'abc': Abc,
    'def': Def,
    'ghi': Ghi,
    'jkl': Jkl,
}
r_type = input('value:')
class_obj = cf.get(r_type, None)
if class_obj:
   class_obj()
utks009
  • 573
  • 4
  • 14