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?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage