2010-06-06 10 views
11

Se faccio la seguenteCopia firma chiamata al decoratore

def mydecorator(f): 
    def wrapper(*args, **kwargs): 
     f(*args, **kwargs) 
    wrapper.__doc__ = f.__doc__ 
    wrapper.__name__ = f.__name__ 
    return wrapper 

@mydecorator 
def myfunction(a,b,c): 
    '''My docstring''' 
    pass 

E quindi digitare help myfunction, ottengo:

Help on function myfunction in module __main__: 

myfunction(*args, **kwargs) 
    My docstring 

Così il nome e docstring vengono copiati correttamente sopra. C'è un modo per copiare anche oltre la firma chiamata effettiva, in questo caso (a, b, c)?

risposta

9

Ecco un esempio di utilizzo di decorator module Michele Simionato per fissare la firma:

import decorator 

@decorator.decorator 
def mydecorator(f,*args, **kwargs): 
    return f(*args, **kwargs) 

@mydecorator 
def myfunction(a,b,c): 
    '''My docstring''' 
    pass 

help(myfunction) 
# Help on function myfunction in module __main__: 

# myfunction(a, b, c) 
#  My docstring 
+0

Questa è una buona risposta, ma crea una dipendenza su un altro terzo non ufficiale. C'è un modo semplice per farlo senza usare il modulo decoratore? –

+0

Il modulo 'decorator' è un singolo file che consiste di <250 linee. Non penso che strappare le parti rilevanti ti farà risparmiare molto codice. Il modo più semplice è installare il modulo decoratore. Si noti che, se non è possibile installarlo a livello di sistema, è sempre possibile salvare una copia locale del 'decorator.py' in una directory nel PYTHONPATH. – unutbu

+0

Questa soluzione non si adatta al mio problema perché 'decorator' assume poco o nessun lavoro sulla funzione decoratore principale e la maggior parte del lavoro viene eseguita nella funzione di ritorno interno. Non è il mio caso: faccio molto lavoro prima di definire la mia funzione restituita. Inoltre, assume io effettivamente chiamare la funzione orinal dall'interno della funzione restituita, ciò non farò (è un sistema RPC) quindi non ho uso per la funzione ricevuto come primo parametro. – lvella

1

Questa funzionalità viene fornita dalla della libreria standard di Python inspect module, in particolare per inspect.getargspec.

>>> import inspect 
>>> def f(a, b, c=0, *args, **kwargs): return 
... 
>>> inspect.getargspec(f) 
ArgSpec(args=['a', 'b', 'c'], varargs='args', keywords='kwargs', defaults=(0,)) 
+2

Questo sembra interessante, ma c'è un modo per impostare effettivamente la firma della chiamata del wrapper in modo che appaia lo stesso di quello della funzione originale quando si usa il comando help? – astrofrog

Problemi correlati