dimanche 14 février 2021

Preferred pattern for enabling and disabling existing decorators?

I would like to switch on/off existing decorators programmatically. An example decorator is profiling, which would be turned on occasionally:

def profile(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print("start profiling")
        ret = func(*args, **kwargs)
        print("finish profiling")
        return ret
    return wrapper

Is there an objectively preferred pattern for achieving this?

One way is:

def switchable_decorator_factory(decorator):
    def switchable_decorator(flag: bool):
        if flag:
            return decorator
        else:
            return lambda x: x
    return switchable_decorator

profile_if = switchable_decorator_factory(profile)

@profile_if(True)
def func(x):
    pass

Another way is:

def enable_decorator_if(decorator, flag: bool):
    def modified_decorator(func):
        if flag:
            return decorator(func)
        else:
            return func

    return modified_decorator

@enable_decorator_if(profile, True)
def func(x):
    pass

Aucun commentaire:

Enregistrer un commentaire