Cómo hacer que los decoradores se enciendan o apaguen opcionalmente

Estoy preguntando, dada una función con un decorador, ¿es posible ejecutar la función sin invocar la llamada del decorador?

Dada una funciónfoo, ¿es posible activar o desactivar opcionalmente un decorador en él?

Dado

@decorator
def foo():
    //do_somthing

¿Es posible correrfoo condecorator ¿Apagado?

Es posible que exista alguna función en la que desee ejecutarlo con o sin el decorador. Por ejemplo (y no es bueno, ya que implica un almacenamiento en caché eficiente) apague el almacenamiento en caché basado en decorador en unfactorial(n) función.

Mi pregunta es similar a esta preguntaOpcionalmente use decoradores en métodos de clase. Discute una buena aplicación de encendido / apagado del decorador (exponiendo como una api);

si tuviera que usar una función, digamosgoo y dar la opción de ejecutargoo con o sin un decorador, probé una forma primitiva y hack para lograr esta funcionalidad opcional de encendido / apagado del decorador de la siguiente manera:

# 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

que salidas:

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]}

que técnicamente funciona, pero creo que es un truco de arranque. no pitónico Y cada vez que se crea una nueva clase de forma recursiva.

La pregunta se mantiene y no pude encontrar una respuesta relevante aquí, así que creé esto, ¿hay alguna forma de activar / desactivar decoradores opcionalmente?

Respuestas a la pregunta(1)

Su respuesta a la pregunta