Декорирование функций Python перед вызовом

У меня есть довольно сложный декоратор, написанный кем-то другим. Я хочу один раз вызвать декорированную версию функции на основе описания или вызвать исходную функцию (не декорированную) в другой раз. Это возможно?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
9
0
8 993
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

С:

decorator(original_function)()

Без:

original_function()

Декоратор - это просто функция, которая принимает функцию в качестве аргумента и возвращает другую. Синтаксис @ не является обязательным. Возможно, просеивание некоторого документация может помочь прояснить ситуацию.

def original_function():
    pass

decorated_function= decorator(original_function)

if use_decorated:
    decorated_function()
else:
    original_function()

Украсить только один раз, а потом выбрать, какую версию назвать.

Вот рецепт, который я придумал. Мне также нужно было сохранить подписи такими же, поэтому я использовал модуль декоратора, но вы могли бы переделать его, чтобы этого избежать. По сути, фокус состоял в том, чтобы добавить к функции атрибут. «Исходная» функция не связана, поэтому вам нужно передать «self» в качестве первого параметра, поэтому я добавил дополнительный код, чтобы проверить это.

# http://www.phyast.pitt.edu/~micheles/python/decorator-2.0.1.zip
from decorator import decorator, update_wrapper

class mustbe : pass

def wrapper ( interface_ ) :
    print "inside hhh"
    def call ( func, self, *args, **kwargs ) :
        print "decorated"
        print "calling %s.%s with args %s, %s" % (self, func.__name__, args, kwargs)
        return interface_ ( self, *args, **kwargs )
    def original ( instance , *args, **kwargs ) :
        if not isinstance ( instance, mustbe ) :
            raise TypeError, "Only use this decorator on children of mustbe"
        return interface_ ( instance, *args, **kwargs )
    call = decorator ( call, interface_ )
    call.original = update_wrapper ( original, call )
    return call

class CCC ( mustbe ):
    var = "class var"
    @wrapper
    def foo ( self, param ) :
        """foo"""
        print self.var, param

class SSS ( CCC ) :
  @wrapper ( hidden_=True )
  def bar ( self, a, b, c ) :
    print a, b, c

if __name__ == "__main__" :
    from inspect import getargspec

    print ">>> i=CCC()"
    i=CCC()

    print ">>> i.var = 'parrot'"
    i.var = 'parrot'

    print ">>> i.foo.__doc__"
    print i.foo.__doc__

    print ">>> getargspec(i.foo)"
    print getargspec(i.foo)

    print ">>> i.foo(99)"
    i.foo(99)

    print ">>> i.foo.original.__doc__"
    print i.foo.original.__doc__

    print ">>> getargspec(i.foo.original)"
    print getargspec(i.foo.original)

    print ">>> i.foo.original(i,42)"
    i.foo.original(i,42)

    print ">>> j=SSS()"
    j=SSS()

    print ">>> j.bar(1,2,3)"
    j.bar(1,2,3)

Другие вопросы по теме