2014-12-02 3 views
1

В методе класса у меня есть набор возможных параметров для одного ключевого слова, каждый из которых имеет другой алгоритм для вычисления чего-то. Чтобы проверить, какой вариант был добавлен в ключевое слово, я создал цепочку if, elif, иначе тоже найду ключевое слово.Опуская long 'if, elif, elif, else' from keyword-arguments

class MyClass: 
    def my_method(self, my_parameter, my_keyword='spacial'): 
     if my_keyword == 'spacial': 
      print('Cool stuf') 
     elif my_keyword == 'discoidal': 
      print('OTHER cool stuff') 
     elif my_keyword == 'temporal': 
      print('You get the gist') 
     else: 
      print('not in options list') 

По-моему, это не очень элегантный способ кодирования этого. Особенно, если список опций продолжает расти. Есть ли способ опустить список команд if, elif, elif, else?

+1

'='? Ты уверен? И где скрылся 'def'? И что там делают струнные литералы? ... При отправке кода примера вы всегда должны делать это так же правильно, как вы можете это сделать. Теперь я отредактировал код для вас, к чему вы, вероятно, * намеревались это сделать. – Carpetsmoker

+1

Всегда оставляйте рабочий код ... – wenzul

+0

Каноническая замена для множества 'elif' - это словарь 'lookup = {'spacial': 'Cool stuf', 'discoidal': 'OTHER cool stuff'}', а затем ' print (lookup [my_keyword]) ', но вам, возможно, придется реорганизовать в отдельные функции, чтобы реализовать это с нетривиальным примером. – jonrsharpe

ответ

2

Использование словаря:

def cool_stuff(param): 
    ... 

def other_cool_stuff(param): 
    ... 

def you_get_the_gist(param): 
    .... 


dispatch_mapping = { 
    'spacial': cool_stuff, 
    'discoidal': other_cool_stuff, 
    'temporal': you_get_the_gist 
} 

Где-то еще:

def my_method(self, param, keyword='spacial'): 
    handler = dispatch_mapping.get(keyword) 
    if handler is None: 
     raise Exception("No handler for %s" % keyword) 
    return handler(param) 
+0

@wenzul Он должен, я обновлял его:) –

+0

Чтобы развернуть/объяснить немного, это использует тот факт, что в функциях Python являются первоклассными объектами; для объяснения см. также: http://stackoverflow.com/questions/245192/what-are-first-class-objects – Carpetsmoker

+0

Для нескольких функций он также будет быстрее, чем if-else из-за сложности поиска по времени словаря O (1). – wenzul

0

Существует всегда, по крайней мере, одно место, где вы должны разделить случаи.

В вашем случае вы устанавливаете строку, а затем сравниваете ее снова.

«Путь» вокруг этого будет заменять настройку вашей строки различными вызовами функции/метода непосредственно, а не маршрутизировать ее внутри функции. Или используйте словарь для сопоставления строк для вызова функции.

0

Использование словаря является хорошей идеей. Однако другой вариант - это отражение, которое функция вызывается строкой.

class MyClass: 
    def handle_spacial(self): 
     print('Cool stuf') 

    def handle_discoidal(self): 
     print('OTHER cool stuff') 

    def handle_temporal(self): 
     print('You get the gist') 

    def default(self): 
     print('not in options list') 

    def my_method(self, my_parameter, my_keyword='spacial'): 
     function_name = "handle_"+my_keyword 
     if hasattr(self, function_name): 
      getattr(self, function_name)() 
     else: 
      self.default() 
0

Лучший способ создать словарь ключевых слов и вариантов, которые будут отображаться и использовать следующим образом:

>>> class MyClass: 
... global mykey_option 
... mykey_option={'spacial':'Cool stuf','discoidal':'OTHER cool stuff','temporal':'You get the gist'} 
... def my_method(self, my_parameter, my_keyword='spacial'): 
...  try: 
...   print(mykey_option[my_keyword]) 
...  except: 
...   print('not in options list') 
... 
>>> x = MyClass() 
>>> x.my_method(1,'discoidal') 
OTHER cool stuff 
>>> x.my_method(1,'spacial') 
Cool stuf 
>>> x.my_method(1,'temporal') 
You get the gist 
>>> x.my_method(1,'newstring') 
not in options list 
+0

Не используйте голые 'except'. Делайте 'кроме KeyError'. В противном случае вы поймаете 'SystemExit' и другие вещи, что хуже, чем это звучит, если, например, stdout - это блок pipe и 'print()'. – Kevin

Смежные вопросы