Вопрос

I have recently got introduced to decorators and I know how the syntax works but I am struggling to know when one is worth applying.

For example, I have a function that returns a random setting value. I want to add on extra functionality where if the settings value that is chosen is a certain value then some of the other settings are disabled. This can easily be achieved by adding this to the end of the function but I could (and have) written a decorator for this. Is this a correct usage?

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)
Это было полезно?

Решение

A function decorator is just a function; you are free to do with it what you want.

Responding to the output of a decorated function is a fine usecase; it'd look something like:

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

where using @functools.wraps() is a good practice to get into when writing decorators; this utility decorator copies across things like the function name, docstring and module name.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top