简体   繁体   中英

Decorator that can interact with the wrapped function's arguments

I am trying to build a decorator that can inspect the wrapped function's arguments, the context for the need is to allow easier validation of certain arguments before they hit the function, avoiding the boiler plate of checking in every place I need said check/validation.

This is not a difficult decorator to write though, and this gets the job done (to make sure a value is not None for example):

def check_arg(func):
    def wrapped(value):
        assert value is not None
        func(value)
    return wrapped

The above example is not production code, it is merely an example of something that will work, but the problem becomes apparent when the function to decorate can have other decorators being used.

In that case, the above decorator example will not work, because value can now be another decorator. I could add another nested function here but it looks like there should be a better way of dealing with it programmatically, plus, it would break whenever the number of decorators change.

How could I get to the arguments of the wrapped function regardless of the number of decorators used by it?

EDIT: I should've noted than I am not simply stacking decorators, I am using one decorator that decorates re-usable decorators. In the example above I would re-use that in this context:

@check_arg
def some_other_decorator(func):
    def wrapped(*args, **kw):
        ... # some interaction here
    return wrapped

As I was writing this edit, I realized that the check_arg decorator was in the wrong place, it should've been in the wrapped function call within the some_other_decorator .

Are you in control of the other decorators? If so, make sure all of them play nice by properly wrapping the calling function:

  import functools
  def check_arg(func):
      @functools.wraps(func)
      def wrapped(value):
          assert value is not None
          func(value)
      return wrapped

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM