2010-09-16 40 views
13

Với một hàm:Làm thế nào tôi có thể thay đổi lập trình argspec của một hàm trong một trình trang trí python?

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

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

Làm thế nào tôi có thể tạo ra một trang trí như vậy mà bare_argspec == decorated_argspec?

(Đối với lý do tại sao, khung gọi hàm được trang trí thực hiện kiểm tra argspec để chọn nội dung cần truyền vào, vì vậy trang trí phải giữ lại cùng một argspec để phát đẹp. Khi tôi đặt câu hỏi này trên #python, Tôi đã có một bài phát biểu dài về lý do tại sao khuôn khổ hút, đó không phải là những gì tôi đang tìm kiếm; Tôi phải giải quyết vấn đề ở đây. Ngoài ra, tôi cũng chỉ quan tâm đến câu trả lời)

+1

Cú phápError: cú pháp không hợp lệ - Tôi nghĩ bạn có nghĩa là 'def func (...' –

Trả lời

12

Michele Simionato's decorator module có một trang trí được gọi là trang trí trong đó bảo tồn hàm argspecs.

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() và/hoặc functools.wraps() đủ tốt?

+6

Không, chúng không bảo toàn argspec. –

2

Có module decorator:

from decorator import decorator 
@decorator 
def trace(func, *args, **kw): 
    print 'calling', func, 'with', args, kw 
    return func(*args, **kw) 

Điều đó làm cho trace một trang trí với argspecs giống như chức năng trang trí. Ví dụ:

>>> @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)) 
Các vấn đề liên quan