toggling decorators

后端 未结 7 1887
伪装坚强ぢ
伪装坚强ぢ 2021-01-04 18:37

What\'s the best way to toggle decorators on and off, without actually going to each decoration and commenting it out? Say you have a benchmarking decorator:



        
7条回答
  •  慢半拍i
    慢半拍i (楼主)
    2021-01-04 18:53

    I've been using the following approach. It's almost identical to the one suggested by CaptainMurphy, but it has the advantage that you don't need to call the decorator like a function.

    import functools
    
    class SwitchedDecorator:
        def __init__(self, enabled_func):
            self._enabled = False
            self._enabled_func = enabled_func
    
        @property
        def enabled(self):
            return self._enabled
    
        @enabled.setter
        def enabled(self, new_value):
            if not isinstance(new_value, bool):
                raise ValueError("enabled can only be set to a boolean value")
            self._enabled = new_value
    
        def __call__(self, target):
            if self._enabled:
                return self._enabled_func(target)
            return target
    
    
    def deco_func(target):
        """This is the actual decorator function.  It's written just like any other decorator."""
        def g(*args,**kwargs):
            print("your function has been wrapped")
            return target(*args,**kwargs)
        functools.update_wrapper(g, target)
        return g
    
    
    # This is where we wrap our decorator in the SwitchedDecorator class.
    my_decorator = SwitchedDecorator(deco_func)
    
    # Now my_decorator functions just like the deco_func decorator,
    # EXCEPT that we can turn it on and off.
    my_decorator.enabled=True
    
    @my_decorator
    def example1():
        print("example1 function")
    
    # we'll now disable my_decorator.  Any subsequent uses will not
    # actually decorate the target function.
    my_decorator.enabled=False
    @my_decorator
    def example2():
        print("example2 function")
    

    In the above, example1 will be decorated, and example2 will NOT be decorated. When I have to enable or disable decorators by module, I just have a function that makes a new SwitchedDecorator whenever I need a different copy.

提交回复
热议问题