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

@decorated 
def g(): 
    pass 

functools.wrapsg के नाम संरक्षण में अपना काम करता है:Functools.wraps का उपयोग करके सजाए गए फ़ंक्शन रैपर के नाम के साथ TypeError उठाता है। क्यूं कर? कैसे बचें?

>>> g.__name__ 
'g' 

लेकिन अगर मैं g लिए एक तर्क पारित, मैं एक TypeError आवरण के नाम वाले मिलती है:

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

यह नाम कहां से आया है? यह संरक्षित कहां है? और क्या अपवाद को g() takes no arguments जैसा दिखने का कोई तरीका है?

+2

संबंधित: http://stackoverflow.com/q/29488327/3001761 – jonrsharpe

उत्तर

8

नाम कोड ऑब्जेक्ट से आता है; दोनों समारोह और कोड वस्तु (बाईटकोड युक्त अन्य लोगों के अलावा, निष्पादित किया जाना है) कि नाम शामिल:

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

कोड वस्तु पर विशेषता केवल पढ़ने के लिए:

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

आप चाहते इसका नाम बदलने के लिए एक पूरी नई कोड ऑब्जेक्ट बनाना है, a previous answer of mine देखें जहां मैंने ऐसा करने के लिए एक फ़ंक्शन को परिभाषित किया है; अपने सजाया समारोह पर rename_code_object() फ़ंक्शन का उपयोग:

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

हालांकि, ध्यान दें कि यह पूरी तरह से नकाब होगा क्या कोड था रन किया जा रहा है! आप आम तौर पर देखना चाहते हैं कि एक सजावटी रैपर शामिल था; यह रैपर है जो अपवाद फेंकता है, मूल कार्य नहीं, आखिरकार।

+0

वास्तव में मैंने अभी आपके दूसरे जवाब से लिंक किया है जहां आप दिखाते हैं कि यह कैसे करना है! 'G = rename_code_object (g, 'g') के बाद, त्रुटि संदेश 'TypeError: g() को वांछित के रूप में कोई तर्क नहीं (1 दिया गया) लेता है। – jonrsharpe

संबंधित मुद्दे

 संबंधित मुद्दे