Introspection to get decorator names on a method?

后端 未结 8 1593
滥情空心
滥情空心 2020-12-01 08:00

I am trying to figure out how to get the names of all decorators on a method. I can already get the method name and docstring, but cannot figure out how to get a list of dec

8条回答
  •  臣服心动
    2020-12-01 08:11

    I've add the same question. In my unit tests I just wanted to make sure decorators were used by given functions/methods.

    The decorators were tested separately so I didn't need to test the common logic for each decorated function, just that the decorators were used.

    I finally came up with the following helper function:

    import inspect
    
    def get_decorators(function):
        """Returns list of decorators names
    
        Args:
            function (Callable): decorated method/function
    
        Return:
            List of decorators as strings
    
        Example:
            Given:
    
            @my_decorator
            @another_decorator
            def decorated_function():
                pass
    
            >>> get_decorators(decorated_function)
            ['@my_decorator', '@another_decorator']
    
        """
        source = inspect.getsource(function)
        index = source.find("def ")
        return [
            line.strip().split()[0]
            for line in source[:index].strip().splitlines()
            if line.strip()[0] == "@"
        ]
    

    With the list comprehension, it is a bit "dense" but it does the trick and in my case it's a test helper function.

    It works if you are intrested only in the decorators names, not potential decorator arguments. If you want to support decorators taking arguments, something like line.strip().split()[0].split("(")[0] could do the trick (untested)

    Finally, you can remove the "@" if you'd like by replacing line.strip().split()[0] by line.strip().split()[0][1:]

提交回复
热议问题