2015-04-28 14 views
11
def decorated(f): 
    @functools.wraps(f) 
    def wrapper(): 
     return f() 
    return wrapper 

@decorated 
def g(): 
    pass 

functools.wraps làm công việc của mình tại bảo quản tên của g:Chức năng được trang trí bằng cách sử dụng functools.wraps tăng TypeError với tên của trình bao bọc. Tại sao? Làm sao để tránh?

>>> g.__name__ 
'g' 

Nhưng nếu tôi vượt qua một cuộc tranh cãi để g, tôi nhận được một TypeError chứa tên của wrapper:

>>> g(1) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: wrapper() takes no arguments (1 given) 

Tên này đến từ đâu? Nó được bảo quản ở đâu? Và có cách nào để làm cho ngoại lệ trông giống như g() takes no arguments?

+2

Liên quan: http://stackoverflow.com/q/29488327/3001761 – jonrsharpe

Trả lời

8

Tên đến từ đối tượng mã; cả hai chức năng và đối tượng mã (có chứa các bytecode được thực hiện, trong số những người khác) chứa tên:

>>> g.__name__ 
'g' 
>>> g.__code__.co_name 
'wrapper' 

Thuộc tính trên đối tượng đang read-only:

>>> g.__code__.co_name = 'g' 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: readonly attribute 

bạn muốn phải tạo một đối tượng mã hoàn toàn mới để đổi tên, xem a previous answer of mine nơi tôi đã xác định một hàm để làm điều đó; bằng cách sử dụng chức năng rename_code_object() về chức năng trang trí của bạn:

>>> g = rename_code_object(g, 'g') 
>>> g(1) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: g() takes no arguments (1 given) 

Lưu ý, tuy nhiên, điều này sẽ hoàn toàn che giấu những gì mã đã được chạy! Bạn thường muốn thấy rằng một wrapper trang trí đã được tham gia; nó là trình bao bọc ném ngoại lệ, chứ không phải hàm ban đầu, sau cùng.

+0

Thực ra tôi vừa mới liên kết với một câu trả lời khác của bạn, nơi bạn chỉ cho bạn cách làm điều đó! Sau 'g = rename_code_object (g, 'g')', thông báo lỗi trở thành 'TypeError: g() không nhận đối số (1 đã cho)' như mong muốn. – jonrsharpe

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