2012-09-24 10 views
8

Duplicar posible:
How can I programmatically change the argspec of a function in a python decorator?preservar argspec al decorar?

argspec es una gran manera de obtener argumentos de una función, pero no funciona cuando la función ha sido decorado:

def dec(func): 
    @wraps(func) 
    def wrapper(*a, **k) 
     return func() 
    return wrapper 


@dec 
def f(arg1, arg2, arg3=SOME_VALUE): 
    return 

import inspect 
print inspect.argspec(f) 

----------- 

ArgSpec(args=[], varargs='a', keywords='k', defaults=None) 

Argspec debe devolver arg1, arg2, arg3. Creo que necesito definir wrapper de manera diferente para no usar *a y **k, pero no sé cómo.

+1

Me alegra que haya un módulo de terceros que resuelva nuestro problema, así que gracias a @MuMind por señalarlo, pero * por qué * no lo maneja la propia biblioteca de Python '' functools.wraps'' decorador, como tú y yo esperábamos? Eso es exactamente para lo que es, después de todo. ¿Informe de error? – pmos

+0

Para los interesados, abrí la lata de gusanos aquí: http://bugs.python.org/issue23764 – pmos

Respuesta

9

El módulo decorator los conserva muy bien:

from decorator import decorator 
@decorator 
def dec(func, *a, **k): 
    return func() 

@dec 
def f(arg1, arg2, arg3=1): 
    return 

import inspect 
print inspect.getargspec(f) 
ArgSpec(args=['arg1', 'arg2', 'arg3'], varargs=None, keywords=None, defaults=(1,)) 

es probable que pueda obtener el mismo efecto mediante la copia manualmente algunos __foo__ atributos de la función a la función de contenedor, pero de todos modos el módulo decorador demuestra es posible y tal vez te dé un punto de partida.

+0

Esto responde mi pregunta, pero me da pena que el módulo de decorador no parezca admitir decoradores que tomen parámetros. – priestc

+0

¿Quieres decir como decorador "fábrica", como '@dec (1, 2)'? –

+0

sí, eso es lo que quise decir – priestc

Cuestiones relacionadas