2012-05-02 9 views
6

Tengo un módulo que decora algunas funciones clave con decoradores personalizados.¿Hay alguna manera de entrar en las funciones decoradas, omitiendo el código de decorador

La depuración de estas funciones con pdb a menudo es un poco molesta, porque cada vez que entro en una función decorada primero tengo que pasar por el código del decorador.

Por supuesto, simplemente configuré el depurador para romper dentro de la función que me interesa, pero como funciones clave se llaman muchas veces desde muchos lugares, por lo que generalmente prefiero comenzar a depurar fuera de la función.

Me trataron de ilustrar con el código, pero no sé si eso ayuda:

def i_dont_care_about_this(fn): 
    @functiontools.wraps(fn) 
    def wrapper(*args, **kwargs): 
     return fn(*args, **kwargs) 
    return wrapper 

@i_dont_care_about_this 
def i_only_care_about_this(): 
    # no use to set pdb here 

def i_am_here(): 
    import pdb; pdb.set_trace() 
    i_only_care_about_this() 

así, ¿hay alguna manera de entrar en i_only_care_about_this de i_am_here sin pasar por i_dont_care_about_this?

Esencialmente Quiero saltar todo el código decorador cuando se utiliza s a (s) tep en una función decorada dado.

+2

¿Cómo se supone AP saber que una función está decorado y en en qué punto se encuentra la función original ¿re? Tendría que adaptar sus decoradores y PDB para hacer algo como esto posible. –

+0

Pensé que podría haber una manera, ya que mi conocimiento de cómo Python maneja los decoradores internamente es algo limitado. –

Respuesta

4

No creo que puedas hacer eso. Cambiaría el significado del paso para ser algo muy diferente.

Sin embargo, hay una forma de lograr algo similar a lo que desea. Establezca un punto de interrupción en su función decorada y una justo antes de que se llame a la función decorada. Ahora, deshabilite el punto de interrupción dentro de la función.

Ahora, cuando ejecuta el código, solo se interrumpirá cuando llegue a la invocación específica que le interese. Una vez que ocurre esa pausa, vuelva a habilitar el punto de interrupción en la función y continúe la ejecución. Esto ejecutará todo el código decorado y dividirá la primera línea de la función decorada.

+0

Hm, creo que OP ya sabe eso, al menos lo describe en la pregunta como una posibilidad que ya ha considerado. –

+0

en realidad no lo he hecho y podría ayudar en algunos casos –

6

Si el decorador es puramente para el registro o cualquier otro comportamiento no funcional, entonces que sea un no-op para la depuración - insertar este código justo después de la definición de i_dont_care_about_this:

DEBUG = False 
# uncomment this line when pdb'ing 
# DEBUG = True 
if DEBUG: 
    i_dont_care_about_this = lambda fn : fn 

Pero si contiene real código activo, entonces usted tendrá que hacer el trabajo usando métodos pdb, como una llamada a conditionalized pdb.set_trace dentro del código dentro del decorador:

BREAK_FLAG = False 
... 
# (inside your function you want to debug) 
if BREAK_FLAG: 
    import pdb; pdb.set_trace() 
... 
# at your critical calling point 
BREAK_FLAG = True 
Cuestiones relacionadas