2010-06-06 29 views
11

Nếu tôi làm như sauSao chép gọi chữ ký để Decorator

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 

Và sau đó gõ help myfunction, tôi nhận được:

Help on function myfunction in module __main__: 

myfunction(*args, **kwargs) 
    My docstring 

Vì vậy, tên và docstring được sao chép một cách chính xác hơn. Có cách nào để sao chép qua chữ ký cuộc gọi thực tế, trong trường hợp này là (a, b, c)?

Trả lời

9

Dưới đây là một ví dụ sử dụng Michele Simionato của decorator module để sửa chữa các chữ ký:

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

Đây là câu trả lời hay nhưng tạo ra sự phụ thuộc vào một bên thứ ba không chính thức khác. Có cách nào đơn giản để làm điều này mà không sử dụng mô-đun trang trí? –

+0

Mô-đun trang trí 'là một tệp đơn chứa <250 dòng. Tôi không nghĩ rằng tách ra các bộ phận có liên quan sẽ giúp bạn tiết kiệm nhiều mã. Cách dễ nhất là cài đặt mô-đun trang trí. Lưu ý rằng nếu bạn không thể cài đặt nó trên toàn hệ thống, bạn luôn có thể lưu một bản sao cục bộ 'decorator.py' vào một thư mục trong PYTHONPATH của bạn. – unutbu

+0

Giải pháp này không phù hợp với vấn đề của tôi bởi vì 'decorator' giả định rất ít hoặc không có công việc nào được thực hiện trên hàm trang trí cha và hầu hết công việc được thực hiện trong hàm trả về bên trong. Đó không phải là trường hợp của tôi: Tôi làm rất nhiều việc trước khi xác định hàm trả về của tôi. Ngoài ra, nó giả sử tôi sẽ thực sự gọi hàm orinal từ bên trong hàm trả về, những gì tôi sẽ không làm (nó là một hệ thống RPC) vì vậy tôi không sử dụng cho hàm nhận được như tham số đầu tiên. – lvella

1

Chức năng này được cung cấp bởi thư viện chuẩn của thư viện chuẩn inspect module của Python, cụ thể là 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

Điều này có vẻ thú vị, nhưng có một cách để thực sự thiết lập chữ ký cuộc gọi của trình bao bọc để nó trông giống như chức năng ban đầu khi sử dụng lệnh trợ giúp? – astrofrog

Các vấn đề liên quan