Wie können Dekorateure wahlweise ein- oder ausgeschaltet werden?
Ich frage, ob es bei einer Funktion mit einem Dekorateur möglich ist, die Funktion auszuführen, ohne den Dekorateur-Aufruf aufzurufen.
Gab eine Funktionfoo
, kann ein Dekorateur optional ein- oder ausgeschaltet werden?
Gegebe
@decorator
def foo():
//do_somthing
Ist es möglich, laufenfoo
mitdecorator
Ausgeschaltet
Möglicherweise gibt es eine Funktion, die Sie mit oder ohne Decorator ausführen möchten. Zum Beispiel (und keine gute, da es effizientes Caching beinhaltet), deaktivieren Sie Decorator-basiertes Caching in einemfactorial(n)
Funktion.
Meine Frage ähnelt dieser FrageVerwenden Sie Dekoratoren optional für Klassenmethoden. Es wird eine gute Anwendung zum Ein- und Ausschalten des Dekorateurs (Belichten als API) erörter
wenn ich eine Funktion verwenden musste, sagen Siegoo
und geben Sie die Option an, entweder @ auszuführgoo
Mit oder ohne Dekorator habe ich einen primitiven, hackigen Weg ausprobiert, um diese optionale Funktion zum Ein- und Ausschalten des Dekorators wie folgt zu erreichen:
# 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
welche Ausgänge:
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]}
was technisch funktioniert, aber ich denke, es ist ein bootstrapped Hack. nicht pythonisch. Und jedes Mal, wenn eine neue Klasse rekursiv erstellt wird.
Die Frage steht und ich konnte hier keine relevante Antwort finden, also habe ich diese Frage erstellt. Gibt es eine Möglichkeit, Dekorateure wahlweise ein- oder auszuschalten?