Я спрашиваю, с помощью функции с декоратором, можно ли запустить функцию без вызова вызова декоратора?Как сделать декораторы необязательно включать или выключать
С учетом функции foo
, можно ли по желанию включить или выключить декоратор на нем?
Учитывая
@decorator
def foo():
//do_somthing
Можно ли запустить foo
с decorator
Выключен?
Может существовать некоторая функция, в которой вы можете запустить ее с помощью декоратора или без него. Например (и не очень хороший, поскольку он включает эффективное кэширование), отключите кеширование на основе декоратора в функции factorial(n)
.
Мой вопрос похож на этот вопрос Optionally use decorators on class methods. В нем обсуждается хорошее применение включения/выключения декоратора (экспозиция как api);
, если я должен был использовать функцию, скажу goo
и дает возможность либо запускать goo
с или без декоратора, я попробовал примитивный, хак способ достичь этого необязательного декоратора включения/выключения функции следующим образом:
# this is the decorator class that executes the function `goo`
class deco(object):
def __init__(self, attr):
print "I am initialized"
self.fn = None
# some args you may wana pass
self.attr = attr
# lets say you want these attributes to persist
self.cid = self.attr['cid']
self.vid = 0
def __call__(self, f):
# the call executes and returns another inner wrapper
def wrap(*args):
# this executes main function - see closure
self.fn = f
self.vid = args[0]
self.closure(*args)
return wrap
def closure(self, *args):
n = args[0]
self.cid[n] = self.vid
#goo = deco(fn, attr)
print 'n',n
# executes function `goo`
self.fn(*args)
class gooClass(object):
class that instantias and wraps `goo`around
def __init__(self, attr, deco):
'''
@param:
- attr: some mutable data structure
- deco: True or False. Whether to run decorator or not
'''
self.attr = attr
self.deco = deco
def __call__(self, *args):
if self.deco:
# initiate deco class with passed args
foo = deco(self.attr)
# now pass the `goo` function to the wrapper inside foo.__class__.__call__
foo = foo(self.goo)
return foo(*args)
else:
# execute w/o decorator
return self.goo(*args)
def goo(self, n):
# recursive goo
if n>0:
print 'in goo',n
#print n
# to recurse, I recreate the whole scene starting with the class
# because of this the args in `deco` Class init never persist
too = gooClass(self.attr, self.deco)
return too(n-1)
else: return n
def Fn(n, decoBool):
# this function is where to start running from
attr = {}
cid = [0]*(n+1)
attr['cid'] = cid
#following wud work too but defeat the purpose - have to define again! foo is goo actually
#@deco(attr)
#def foo(n):
# if n>0:
# print 'in foo',n
# #print n
# return foo(n-1)
# else: return n
#return foo(n), attr
# create the gooClass and execute `goo` method instance
foo = gooClass(attr, decoBool)
print foo(n)
return foo
res = Fn(5, True)
print res.attr
print "="*10
res = Fn(5, False)
print res.attr
, который выводит:
I am initialized
n 5
in goo 5
I am initialized
n 4
in goo 4
I am initialized
n 3
in goo 3
I am initialized
n 2
in goo 2
I am initialized
n 1
in goo 1
I am initialized
n 0
None
{'cid': [0, 1, 2, 3, 4, 5]}
==========
in goo 5
in goo 4
in goo 3
in goo 2
in goo 1
0
{'cid': [0, 0, 0, 0, 0, 0]}
который технически работает, но я думаю, что это бутстрапируемые хаки. не пифонов. И каждый раз новый класс создается рекурсивно.
Вопрос стоит, и я не мог найти здесь одного релевантного ответа, поэтому я создал это, есть ли способ включить или отключить Декораторы?
Подсказка: рецензенты видеть ваше изменение комментарий и подразумевающее вы должны говорить вплоть до SO сообщества детсадовцев не является хорошим способом, чтобы мотивировать их заново на ваш вопрос. Кроме того, вы согласитесь, что у вас есть механизм, чтобы отключить декор во время выполнения? У меня есть что-то, где в моем декораторе я ищу, что debugFlag включен; если он не включен, я заменю мою функцию декоратора фиктивной оберткой. У этого есть небольшое количество накладных расходов, но недостаточно для того, чтобы попытаться придумать что-то более экзотическое (но это помогает, что у меня есть только один декоратор и немного) – Foon
@Foon Мы все пытаемся помочь друг другу и очень выгода. Если я смогу сделать сложную/беспорядочную ситуацию, а Dumb это до уровня детского сада, я думаю, что я сделал Великую работу, объясняя вещи. , Каждый раз, когда я вижу этот вопрос, я стараюсь его опустить. Если это имеет смысл для вас, попробуйте эту перспективу. Надеюсь, в будущем у вас не будет впечатления о том, что я высмеиваю любое трудолюбивое уважаемое сообщество. Да, я согласен с любыми входами и импровизациями. Проверьте 'decoBool' и' deco' - в моем коде это ваш debugFlag? – user2290820
Я постараюсь добавить в код некоторые вспомогательные документы/комментарии. Это будет полезно, но здесь слишком поздно. Я сделаю это завтра. – user2290820