Самоанализ для получения имен декоратора на методе?

Я пытаюсь выяснить, как получить имена всех декораторов на методе. Я могу уже получить имя метода и docstring, но не могу выяснить, как получить список декораторов.

32
задан Tony 12 July 2010 в 20:30
поделиться

6 ответов

Если вы можете изменить способ вызова декораторов с

class Foo(object):
    @many
    @decorators
    @here
    def bar(self):
        pass

на

class Foo(object):
    @register(many,decos,here)
    def bar(self):
        pass

то вы можете зарегистрировать декораторы таким образом:

def register(*decorators):
    def register_wrapper(func):
        for deco in decorators[::-1]:
            func=deco(func)
        func._decorators=decorators        
        return func
    return register_wrapper

Например:

def many(f):
    def wrapper(*args,**kwds):
        return f(*args,**kwds)
    return wrapper

decos = here = many

class Foo(object):
    @register(many,decos,here)
    def bar(self):
        pass

foo=Foo()

Здесь мы обращаемся к кортежу декораторов:

print(foo.bar._decorators)
# (<function many at 0xb76d9d14>, <function decos at 0xb76d9d4c>, <function here at 0xb76d9d84>)

Здесь мы печатаем только имена декораторов:

print([d.func_name for d in foo.bar._decorators])
# ['many', 'decos', 'here']
29
ответ дан 27 November 2019 в 20:18
поделиться

Это потому, что декораторы - это «синтаксический сахар». Допустим, у вас есть следующий декоратор:

def MyDecorator(func):
    def transformed(*args):
        print "Calling func " + func.__name__
        func()
    return transformed

И вы применяете его к функции:

@MyDecorator
def thisFunction():
    print "Hello!"

Это эквивалентно:

thisFunction = MyDecorator(thisFunction)

Вы можете встроить «историю» в объект функции, возможно, если вы контролируете декораторы. Бьюсь об заклад, есть другой умный способ сделать это (возможно, переопределив присвоение), но, к сожалению, я не так хорошо разбираюсь в Python. : (

3
ответ дан 27 November 2019 в 20:18
поделиться

Нельзя, но еще хуже то, что существуют библиотеки, помогающие скрыть тот факт, что вы декорировали функцию для начала. Смотрите Functools или библиотеку decorator (@decorator, если я смог ее найти) для получения дополнительной информации.

1
ответ дан 27 November 2019 в 20:18
поделиться

Это невозможно сделать обычным способом, потому что

@foo
def bar ...

в точности совпадает с

def bar ...
bar = foo (bar)

. Вы можете сделать это в некоторых особых случаях, например, вероятно, @staticmethod , анализируя объекты функций, но не лучше, чем это.

0
ответ дан 27 November 2019 в 20:18
поделиться

Как Фейсал отмечает , декораторы могут сами прикреплять метаданные к функции, но, насколько мне известно, это не делается автоматически.

2
ответ дан 27 November 2019 в 20:18
поделиться

That's not possible in my opinion. Декоратор - это не какой-то атрибут или метаданные метода. Декоратор - это удобный синтаксис для замены функции результатом вызова функции. Подробнее см. в http://docs.python.org/whatsnew/2.4.html?highlight=decorators#pep-318-decorators-for-functions-and-methods.

0
ответ дан 27 November 2019 в 20:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: