2014-04-23 1 views
0

Я недавно познакомился с декораторами, и я знаю, как работает синтаксис, но я изо всех сил стараюсь понять, когда это стоит.Правильное использование декоратора python

Например, у меня есть функция, которая возвращает случайное значение настройки. Я хочу добавить дополнительную функциональность, где, если выбранное значение настроек является определенным значением, тогда некоторые другие настройки отключены. Этого можно легко достичь, добавив это в конец функции, но я мог (и имел) написать для этого декоратор. Правильно ли это?

def disable_setting(func): 
    '''A decorator that settings depending on the Acquisition Mode set''' 

    def wrap_disable(self, *args, **kwargs): 
     chosen_value = func(self, *args, **kwargs)[1] 
     if chosen_value != "Accumulate": 
      for setting in self.settings: 
       if setting[0] == "Accumulation Number": 
        setting[1] = 1 
      if chosen_value != "Kinetic": 
       for setting in self.settings: 
        if setting[0] == "Kinetic Series Length" or "Cycle Time": 
         setting[1] = 1 

############################################################# 

@disable_setting 
def random_setting(self, options): 
    if type(options) is list: 
     if len(options) == 1: 
      options.append(options[0] + 1) # Specify static value by the inclusion of only on variable 
     if len(options) == 2: 
      options.append(1) # To allow for the settings with a step the default step value must be stated 
     return randrange(options[0], options[1], options[2]) 
    elif type(options) is dict: 
     return choice(options) 
+0

Да, укажите код, пожалуйста. – msvalkon

+4

Если вы не планируете применять декоратор к нескольким функциям, вам следует просто изменить функцию напрямую. Используйте декораторы для инкапсуляции или рефакторинга. – chepner

+0

@msvalkon Я включил код в соответствии с запросом. – Marmstrong

ответ

3

Декоратор функции - это просто функция; вы можете делать все, что хотите.

Реагирование на результат декорированной функции - прекрасная утилита; было бы выглядеть примерно так:

from functools import wraps 


def yourdecorator(func): 
    @wraps(func): 
    def wrapper(*args, **kw): 
     result = func(*args, **kw) 
     if result in certain_values: 
      adjust_other_configuration() 
     return result 
    return wrapper 

, где использование @functools.wraps() является хорошей практикой, чтобы попасть в при написании декораторов; этот декоратор утилиты копирует такие вещи, как имя функции, имя docstring и имя модуля.