Get python decorator arguments at run time

De openkb
Aller à : Navigation, rechercher

Sommaire

Questions

Is there any kind of way to get the arguments of a decorator function at run time? The project I m working on is huge and it would be a huge effort to rewrite the affected code. I need a dynamic solution to list all categories assigned to a list of functions. For this I want to avoid super hacky solutions, like regexing through all my modules. Can this be done by inspecting the frames from the call stack?

In our environment the functions are object methods, and we use chained decorators as well. For the ease of understanding I put together this bit of code.

If this is not possible, I can put together another decorator for parts of the project, although it would add much more complexity. But any suggestion to solve my issue is welcome.

def check(*args):
    # do something project relevant, so just return True
    return True

def decorate(*categories):
    def wrap(f):
        def wrap_check_categories(*args, **kwargs):
            if check(*categories):
                return f(*args, **kwargs)
            else:
                raise Exception
        return wrap_check_categories
    return wrap

def get_categories(f):
       Returns decorator parameters   
    # ... do some magic here
    raise NotImplementedError

@decorate( foo ,  bar )
def fancy_func(*args, **kwargs):
    return args, kwargs

def main():
    ## should output [ foo ,  bar ]
    print get_categories(fancy_func)

if __name__ ==  __main__ :
    main()

Answers

Modify the decorator to store the categories in an attribute (e.g. _args) of the decorated function:

def check(*args):
    # do something project relevant, so just return True
    return True

def decorate(*categories):
    def wrap(f):
        def wrap_check_categories(*args, **kwargs):
            if check(*categories):
                return f(*args, **kwargs)
            else:
                raise Exception
        wrap_check_categories._args = categories    # <-- store the categories
        return wrap_check_categories
    return wrap

def get_categories(f):
       Returns decorator parameters   
    # ... do some magic here
    return f._args

@decorate( foo ,  bar )
def fancy_func(*args, **kwargs):
    return args, kwargs

def main():
    ## should output [ foo ,  bar ]
    print get_categories(fancy_func)

if __name__ ==  __main__ :
    main()

yields

( foo ,  bar )

Source

License : cc by-sa 3.0

http://stackoverflow.com/questions/34908212/get-python-decorator-arguments-at-run-time

Related

Outils personnels
Espaces de noms

Variantes
Actions
Navigation
Outils