python - Long elif chains vs dictionary with exec() -


i novice python , have read lot of tutorials on how code. 1 thing keep popping never write same line of code multiple times. unsure if long elif arguments count that, me looks bad code.

for exaple:

class answers(object):     def __init__(self):         self.x = 'hello world'      def knight(self):         print('neee!')     def bunny(self):         print('rawwww!')     def pesant(self):         print('witch!')     def dingo(self):         print('bad, wicked, naughty zoot!') foo = answers()     egg = input("sounds:")  if egg == "knight":     foo.knight() elif egg == 'bunny':     foo.bunny() elif egg == 'pesant':     foo.pesant() elif egg == 'dingo':     foo.dingo() else:     print("i don't know?") 

that works think following code looks cleaner.

class answers(object):     def __init__(self):         self.x = 'hello world'      def knight(self):         print('neee!')     def bunny(self):         print('rawwww!')     def pesant(self):         print('witch!')     def dingo(self):         print('bad, wicked, naughty zoot!')  foo = answers() responce = {'knight': 'foo.knight()', 'bunny': 'foo.bunny()', 'pesant': 'foo.pesant()', 'dingo': 'foo.dingo()'}  while true:     try:         egg = input('sounds:')         exec(responce[egg])     except keyerror:         print("i don't know") 

both lines of code same thing, matter use or 1 better other?

side note, know exec() should not used not find way assign function string.

you can assign function name variable if skip () , arguments

responce = {     'knight': foo.knight,     'bunny': foo.bunny,     'pesant': foo.pesant,     'dingo': foo.dingo, } 

and can run using () (with expected arguments)

responce[egg]()  #responce[egg](arg1, arg2, ...) # if function require arguments 

full code

class answers(object): # camelcase name class - see pep8 document      def __init__(self):         self.x = 'hello world'      def knight(self):         print('neee!')      def bunny(self):         print('rawwww!')      def pesant(self):         print('witch!')      def dingo(self):         print('bad, wicked, naughty zoot!')  foo = answers()  responce = {     'knight': foo.knight,     'bunny': foo.bunny,     'pesant': foo.pesant,     'dingo': foo.dingo, }  while true:     try:         egg = input('sounds:')         responce[egg]() # call function     except keyerror:         print("i don't know") 

btw: way can use function name argument function.

it use in tkinter assign function button

button( ..., text="knight", command=foo.knight) 

or assign function event

bind('<button-1>', foo.knight) 

if need assign function arguments can use lambda function.

version python3:

responce = {     'knight': lambda:print('neee!'),     'bunny': lambda:print('rawwww!'),     'pesant': lambda:print('witch!'),     'dingo': lambda:print('bad, wicked, naughty zoot!'), } 

version python2:

print in python2 not function lambda not work print - have create function.

def show(text):     print text  responce = {     'knight': lambda:show('neee!'),     'bunny': lambda:show('rawwww!'),     'pesant': lambda:show('witch!'),     'dingo': lambda:show('bad, wicked, naughty zoot!'), } 

edit: without functions in dictionary :)

# --- classes ---  class answers(object):      def __init__(self):          # todo: read file csv or json         #         # import json          #         # open("data.json") f:          #     self.data = json.load(f)          self.data = {             'knight': 'neee!',             'bunny': 'rawwww!',             'pesant': 'witch!',             'dingo': 'bad, wicked, naughty zoot!',         }      def response(self, text):         try:             return self.data[text]         except keyerror:             return "i don't know"  # --- functions ---    # empty  # --- main ---  foo = answers()  while true:      egg = input('sounds: ').lower()      if egg == 'exit':         break      print(foo.response(egg))  # ---  print("good bye!") 

Comments