Get python decorator arguments at runtime

Is there a way to get decorator function arguments at runtime? 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 function list. To do this, I want to avoid super hacking solutions, such as reusing all of my modules. Can this be done by checking frames from the call stack?

In our environment, functions are object methods, and we also use chained decorators. For ease of understanding, I have compiled this bit of code.

If this is not possible, I can build another decorator for parts of the project, although it will add much more complexity. But any suggestion to solve my problem 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()
+4
1

, (, _args) :

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()

('foo', 'bar')
+2

Source: https://habr.com/ru/post/1625186/


All Articles