Histoire originale: Comment obtenir la méthode décorée en Python
Dans le blog d'origine, j'ai utilisé le module * inspect *, mais il est pratique d'utiliser le module * ast *.
find_decorator.py 
# -*- coding: utf-8 -*-
import ast
source = """
class Sample(object):
    @foo_decorator2
    @foo_decorator1
    def foo(self):
        pass
    @bar_decorator
    def bar(self):
        pass
    def baz(self):
        pass
@hoge_decorator2
@hoge_decorator1
def hoge(x):
    pass
def fuga(x):
    pass
"""
class FindDecorator(ast.NodeVisitor):
    def visit_FunctionDef(self, node):
        decorators = node.decorator_list
        if decorators:
            print('decorated: {}'.format(node.name))
            for name in decorators:
                print('decorator: {}'.format(name.id))
            print('-' * 32)
        return node
FindDecorator().visit(ast.parse(source))
Comme ça.
$ python find_decorator.py 
decorated: foo
decorator: foo_decorator2
decorator: foo_decorator1
--------------------------------
decorated: bar
decorator: bar_decorator
--------------------------------
decorated: hoge
decorator: hoge_decorator2
decorator: hoge_decorator1
--------------------------------
Post-scriptum: J'ai également pu obtenir dynamiquement le code source d'un module en utilisant * inspect.getsource *.
3.4
# -*- coding: utf-8 -*-
import ast
import inspect
import sys
def foo_decorator2(func): pass
def foo_decorator1(func): pass
def bar_decorator(func): pass
def hoge_decorator2(func): pass
def hoge_decorator1(func): pass
class Sample(object):
    @foo_decorator2
    @foo_decorator1
    def foo(self):
        pass
    @bar_decorator
    def bar(self):
        pass
    def baz(self):
        pass
@hoge_decorator2
@hoge_decorator1
def hoge(x):
    pass
def fuga(x):
    pass
class FindDecorator(ast.NodeVisitor):
    def visit_FunctionDef(self, node):
        decorators = node.decorator_list
        if decorators:
            print('decorated: {}'.format(node.name))
            for name in decorators:
                print('decorator: {}'.format(name.id))
            print('-' * 32)
        return node
module = sys.modules[__name__]
source = inspect.getsource(module)
FindDecorator().visit(ast.parse(source))
Vous pouvez obtenir le code source de l'objet passé dans l'argument de * inspect.getsource *. Ici, le module lui-même est passé, mais les classes et les fonctions peuvent également être passées.
Recommended Posts