2013-02-05 33 views
25

मैं विभिन्न कार्यों के ऑडिटिंग को संभालने के लिए एक सजावटी का उपयोग करना चाहता हूं (मुख्य रूप से Django दृश्य कार्य, लेकिन विशेष रूप से नहीं)। ऐसा करने के लिए मैं फ़ंक्शन पोस्ट-निष्पादन - यानी कार्य सामान्य के रूप में चलाता है, और यदि यह अपवाद के बिना लौटाता है, तो सजावटी इस तथ्य को लॉग करता है।सजाए गए फ़ंक्शन के पूरा होने के बाद मुझे पाइथन सजावट कैसे चलाया जा सकता है?

कुछ की तरह:

@audit_action(action='did something') 
def do_something(*args, **kwargs): 
    if args[0] == 'foo': 
     return 'bar' 
    else: 
     return 'baz' 

कहाँ audit_action केवल समारोह पूरा कर लिया है के बाद चलाए जा सकें।

उत्तर

26

सजावटी आमतौर पर एक रैपर फ़ंक्शन लौटाते हैं; लिपटे फ़ंक्शन का आविष्कार करने के बाद बस अपना तर्क रैपर फ़ंक्शन में रखें। अपने do_something (do_something = decorator_func(do_something))

def audit_action(action): 
    def decorator_func(func): 
     def wrapper_func(*args, **kwargs): 
      # Invoke the wrapped function first 
      retval = func(*args, **kwargs) 
      # Now do something here with retval and/or action 
      print 'In wrapper_func, handling action {!r} after wrapped function returned {!r}'.format(action, retval) 
      return retval 
     return wrapper_func 
    return decorator_func 

तो audit_action(action='did something') एक डेकोरेटर कारखाना है कि एक scoped decorator_func देता है, जो सजाने के लिए इस्तेमाल किया जाता है।

सजावट के बाद, आपके do_something संदर्भ को wrapper_func द्वारा प्रतिस्थापित किया गया है। कॉलिंग wrapper_func() मूल do_something() को कॉल करने का कारण बनता है, और उसके बाद रैपर func में आपका कोड चीजें कर सकता है।

>>> do_something('foo') 
In wrapper_func, handling action 'did something' after wrapped function returned 'bar' 
'bar' 
+2

आपके पास कोई विचार के कितने अलग अलग संयोजन हैं:

उपरोक्त कोड, अपने उदाहरण समारोह के साथ संयुक्त, निम्न उत्पादन देता है सजावटी, रैपर, func और retvals मैं इसे काम करने के लिए कोशिश करने के लिए इस्तेमाल किया। न केवल कोड के लिए धन्यवाद, बल्कि स्पष्टीकरण के लिए। –

3

आपका डेकोरेटर इसे यहाँ ही संभाल कर सकते हैं, जैसे

def audit_action(function_to_decorate): 
    def wrapper(*args, **kw): 
     # Calling your function 
     output = function_to_decorate(*args, **kw) 
     # Below this line you can do post processing 
     print "In Post Processing...." 
    return wrapper 
+0

उदाहरण के लिए ओपी ने एक सजावट फैक्ट्री का इस्तेमाल किया जिसे 'एक्शन' तर्क कहा जाता है। आपको स्कोपिंग या कक्षा की एक और परत की आवश्यकता है .. –

+0

ओपी के उदाहरण के अनुसार उत्तर अपडेट किया गया :) – avasal