2010-09-16 28 views
13

bir işlevi göz önüne alındığında:Python dekoratördeki bir işlevin argspecini nasıl programlayabilirim?

nasıl bare_argspec == decorated_argspec böyle bir dekoratör oluşturabilir

def func(f1, kw='default'): 
    pass 
bare_argspec = inspect.getargspec(func) 

@decorator 
def func2(f1, kw='default'): 
    pass 
decorated_argspec = inspect.getargspec(func2) 
?

(Niçin dekore edilmiş işlevi çağıran çerçevenin neyi geçeceğini seçmek için argspec denetimi yapar, bu nedenle dekoratörün güzel çalmak için aynı argspec'i tutması gerekir. #python hakkında bu soruyu sorduğumda, Çerçevenin neden berbat olduğu konusunda uzun bir konuşma yaptım, aradığım şey değil, buradaki problemi çözmek zorundayım. Ayrıca, ben de sadece cevaba ilgi duyuyorum.)

+1

SyntaxError: geçersiz sözdizimi - Sana 'def fonk (...' –

cevap

12

Michele Simionato'nun decorator module, işlev argspeclerini koruyan dekoratör adlı bir dekoratöre sahiptir.

import inspect 
import decorator 

def func(f1, kw='default'): 
    pass 
bare_argspec = inspect.getargspec(func) 
print(bare_argspec) 
# ArgSpec(args=['f1', 'kw'], varargs=None, keywords=None, defaults=('default',)) 

@decorator.decorator 
def mydecorator(func,*args,**kw): 
    result=func(*args,**kw) 
    return result 

@mydecorator 
def func2(f1, kw='default'): 
    pass 
decorated_argspec = inspect.getargspec(func2) 
print(decorated_argspec) 
# ArgSpec(args=['f1', 'kw'], varargs=None, keywords=None, defaults=('default',)) 

assert(bare_argspec==decorated_argspec) 
0

functools.update_wrapper() ve/veya functools.wraps() yeterince iyi mi?

+6

Hayır'ı demek düşünüyorum; onlar argspec korumuyor. –

2

decorator modül vardır:

trace dekore işleviyle aynı argspecs bir dekoratör yapar
from decorator import decorator 
@decorator 
def trace(func, *args, **kw): 
    print 'calling', func, 'with', args, kw 
    return func(*args, **kw) 

. Örnek:

>>> @trace 
... def f(x, y=1, z=2, *args, **kw): 
...  pass 

>>> f(0, 3) 
calling f with (0, 3, 2), {} 

>>> from inspect import getargspec 
>>> print getargspec(f) 
ArgSpec(args=['x', 'y', 'z'], varargs='args', keywords='kw', defaults=(1, 2)) 
İlgili konular