python 如何获取函数上的装饰器元信息?以及知道装饰器,如何获取被装饰过的函数信息?

@decorator_a
def func_a():
    pass
    
@decorator_b(arg)
@decorator_a
def func_b():
    pass

如上所示,若我已知:

func = func_a
deco = decorator_a

请问:

  • 我如何获得func上装饰器的元信息?

如:

meta = get_func_decorator(func)
print(meta.__name__)
------
decorator_a
  • 我如何获得deco装饰过的函数信息?

如:

meta = get_deco_functions(deco)
print([x.__name__ for x in meta])
---------
[func_a, func_b]

谢谢大佬指教!

阅读 7.3k
1 个回答

估计没有一般性的方法,因为有些库可以帮助隐藏已修饰函数的事实。这里有一些非通用的做法,可以参考:

添加实际的内省方法来做到这一点,

要检查的代码:

def template(func):
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper

baz = template
che = template

class Foo(object):
    @baz
    @che
    def bar(self):
        pass

现在,可以使用以下内容检查上述Foo类...

import ast
import inspect

def get_decorators(cls):
    target = cls
    decorators = {}

    def visit_FunctionDef(node):
        decorators[node.name] = []
        for n in node.decorator_list:
            name = ''
            if isinstance(n, ast.Call):
                name = n.func.attr if isinstance(n.func, ast.Attribute) else n.func.id
            else:
                name = n.attr if isinstance(n, ast.Attribute) else n.id

            decorators[node.name].append(name)

    node_iter = ast.NodeVisitor()
    node_iter.visit_FunctionDef = visit_FunctionDef
    node_iter.visit(ast.parse(inspect.getsource(target)))
    return decorators

print get_decorators(Foo)

应该会打印出:

{'bar': ['baz', 'che']}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏