Действительно ли возможно заменить декоратора функции/метода во времени выполнения? [Python]

используйте глобальную область действия для вашего $ con и помещаем ее в вашу функцию getPosts () следующим образом.

function getPosts() {
global $con;
$query = mysqli_query($con,"SELECT * FROM Blog");
while($row = mysqli_fetch_array($query))
    {
        echo "<div class=\"blogsnippet\">";
        echo "<h4>" . $row['Title'] . "</h4>" . $row['SubHeading'];
        echo "</div>";
    }
}
19
задан Geo 13 March 2009 в 13:42
поделиться

5 ответов

Я не знаю, существует ли способ "заменить" декоратора, как только он был применен, но я предполагаю, что, вероятно, нет, потому что функция была уже изменена.

Вы могли бы, так или иначе, применить декоратора во времени выполнения на основе некоторого условия:

#!/usr/bin/env python

class PrintCallInfo:
    def __init__(self,f):
        self.f = f
    def __call__(self,*args,**kwargs):
        print "-->",self.f.__name__,args,kwargs
        r = self.f(*args,**kwargs)
        print "<--",self.f.__name__,"returned: ",r
        return r

# the condition to modify the function...
some_condition=True

def my_decorator(f):
    if (some_condition): # modify the function
        return PrintCallInfo(f)
    else: # leave it as it is
        return f

@my_decorator
def foo():
    print "foo"

@my_decorator
def bar(s):
    print "hello",s
    return s

@my_decorator
def foobar(x=1,y=2):
    print x,y
    return x + y

foo()
bar("world")
foobar(y=5)
6
ответ дан 30 November 2019 в 04:33
поделиться

Как упомянутый Miya, можно заменить декоратора другой функцией любая точка, прежде чем интерпретатор доберется до того объявления функции. Однако, как только декоратор применяется к функции, я не думаю, что существует способ динамично заменить декоратора другим. Так, например:

@aDecorator
def myfunc1():
    pass

# Oops! I didn't want that decorator after all!

myfunc1 = bDecorator(myfunc1)

не будет работать, потому что myfunc1 больше не является функцией, которую Вы первоначально определили; это было уже обернуто. Лучший подход здесь должен вручную применить декораторов, oldskool-стиль, т.е.:

def myfunc1():
    pass

myfunc2 = aDecorator(myfunc1)
myfunc3 = bDecorator(myfunc1)

Редактирование: Или, чтобы быть немного более ясным,

def _tempFunc():
    pass

myfunc1 = aDecorator(_tempFunc)
myfunc1()
myfunc1 = bDecorator(_tempFunc)
myfunc1()
15
ответ дан 30 November 2019 в 04:33
поделиться

Вот потрясающее , рецепт для получения Вас запустился . В основном идея состоит в том, чтобы передать экземпляр класса в декоратора. Можно тогда установить атрибуты на экземпляре класса (сделайте его Borg, если Вам нравится), и использование, что для управления поведением декоратора самим.

Вот пример:

class Foo:
    def __init__(self, do_apply):
        self.do_apply = do_apply

def dec(foo):
    def wrap(f):
        def func(*args, **kwargs):
            if foo.do_apply:
                # Do something!
                pass 
            return f(*args, **kwargs)
        return func
    return wrap

foo = Foo(False)
@dec(foo)
def bar(x):
    return x

bar('bar') 
foo.do_apply = True 
# Decorator now active!
bar('baz')

Естественно, можно также включить "декоратора декоратора" для сохранения подписей, и т.д.

4
ответ дан 30 November 2019 в 04:33
поделиться

Если декоратор является функцией, просто замените ее.

aDecorator = otherDecorator
-2
ответ дан 30 November 2019 в 04:33
поделиться

Если Вы хотите к изменению explicitely декоратора, Вы могли бы также выбрать более явный подход вместо того, чтобы создать украшенную функцию:

deco1(myfunc1, arg1, arg2)
deco2(myfunc1, arg2, arg3)

deco1 () и deco2 () применил бы функциональность, которую Ваши декораторы обеспечивают и называют myfunc1 () с аргументами.

1
ответ дан 30 November 2019 в 04:33
поделиться
Другие вопросы по тегам:

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