Is there a way for a python function to know it is getting decorated at module load time?
例如:
1 2 3 4 5 6 7 | def decorator(func): def nested(*args, **kwargs): return func(*args, **kwargs) return nested @decorator def decorated(): pass |
有没有办法让装修人员知道它正在装修?
可以使用使用
1 2 3 4 5 6 7 8 9 10 11 12 | import inspect import ast from textwrap import dedent class CheckDecorators(ast.NodeVisitor): def visit_FunctionDef(self, node): if len(node.decorator_list) > 1: print("function '%s' is decorated by: %s" % (node.name, ', '.join(ast.dump(decorator) for decorator in node.decorator_list if not isinstance(decorator, ast.Name) or decorator.id != 'check_decorators'))) def check_decorators(func): CheckDecorators().visit(ast.parse(dedent(inspect.getsource(func)))) return func |
号
以便:
1 2 3 4 5 6 7 8 9 | def decorator(func): def nested(*args, **kwargs): return func(*args, **kwargs) return nested @decorator @check_decorators def decorated(): pass |
将输出:
1 | function 'decorated' is decorated by: Name(id='decorator', ctx=Load()) |
。
下面是一个部分解决方案,它适用于与示例完全类似的闭包。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import inspect def decorator(func): def nested(*args, **kwargs): return func(*args, **kwargs) return nested @decorator def decorated(): pass def not_decorated(): pass print(inspect.getclosurevars(decorated).nonlocals) print(inspect.getclosurevars(not_decorated).nonlocals) # => {'func': <function decorated at 0x10e1408c8>} # => {} |
像您这样的修饰函数将有闭包变量,尽管不能保证其他函数不会。
另外,在EDOCX1中还有其他可以玩的东西。另外,如果一开始使用