2012-09-24 9 views
8

Powiel możliwe:
How can I programmatically change the argspec of a function in a python decorator?zachować dekorację argspec podczas dekorowania?

argspec to świetny sposób, aby uzyskać argumenty funkcji, ale to nie działa, gdy funkcja został odznaczony:

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 powinien zwrócić arg1, arg2, arg3. Myślę, że muszę zdefiniować wrapper inaczej, niż nie używać *a i **k, ale nie wiem jak.

+1

Cieszę się, że istnieje moduł trzeciej strony, który rozwiązuje nasz problem, więc dzięki @MuMind za wskazanie go, ale * dlaczego * nie jest obsługiwane przez własną bibliotekę Pythona '' functools.wraps'' dekorator, jak oboje się spodziewaliśmy? W końcu to jest właśnie to. Zgłoszenie błędu? – pmos

+0

Dla zainteresowanych otworzyłem puszkę z robakami: http://bugs.python.org/issue23764 – pmos

Odpowiedz

9

Moduł decorator zachowuje je w porządku:

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,)) 

Prawdopodobnie można uzyskać ten sam efekt poprzez ręczne kopiowanie niektórych __foo__ atrybuty z funkcji do funkcji otoki, ale mimo to moduł dekorator demonstruje to jest możliwe i może daje ci punkt wyjścia.

+0

To odpowiada na moje pytanie, ale jestem zdruzgotany, że moduł dekoratora nie obsługuje dekoratorów, które przyjmują parametry. – priestc

+0

Masz na myśli dekoratora "fabryka", jak '@dec (1, 2)'? –

+0

tak to właśnie miałem na myśli – priestc

Powiązane problemy