2016-04-05 11 views
5

मैं thecodeship पर एक महान ट्यूटोरियल से सजावटी के बारे में कुछ सीख रहा हूं लेकिन मुझे एक उदाहरण से भ्रमित पाया गया है।पायथन सजावट उदाहरण

पहला सजावट इसके बाद एक सजावट के लिए एक स्पष्टीकरण दिया जाता है।

def p_decorate(func): 
    def func_wrapper(name): 
     return "<p>{0}</p>".format(func(name)) 
    return func_wrapper 

def get_text(name): 
    return "lorem ipsum, {0} dolor sit amet".format(name) 

my_get_text = p_decorate(get_text) 

print my_get_text("John") 

अब यह मुझे समझ में आता है। एक सजावट बस एक समारोह के लिए एक रैपर है। और इन लोगों में स्पष्टीकरण में कहा गया है कि एक सजावट एक ऐसा कार्य है जो तर्क के रूप में एक और कार्य करता है, एक नया कार्य उत्पन्न करता है, और जेनरेट किए गए फ़ंक्शन को कहीं भी उपयोग करने के लिए देता है।

और अब ऊपर कोड के बराबर है:

def p_decorate(func): 
    def func_wrapper(name): 
     return "<p>{0}</p>".format(func(name)) 
    return func_wrapper 

@p_decorate 
def get_text(name): 
    return "lorem ipsum, {0} dolor sit amet".format(name) 

print get_text("John") 

मेरा मानना ​​है कि मैं जिस तरह से जब कोई तर्क दिया एक डेकोरेटर आरंभ नहीं हो जाता समझते हैं। अगर मैं ग़लत हूं तो मेरी गलती सुझाएं।

  • डिफ़ॉल्ट रूप से डेकोरेटर समारोह get_text में गुजरता है और क्योंकि p_decorate एक समारोह func_wrapper देता है, हम सच्चा बयान get_text = func_wrapper साथ खत्म।

मेरे लिए महत्वपूर्ण है कि पहला कोड ब्लॉक बराबर है, क्योंकि मैं देखता हूं और समझता हूं कि सजावट कैसा व्यवहार कर रही है। , फिर

def tags(tag_name): 
    def tags_decorator(func): 
     def func_wrapper(name): 
      return "<{0}>{1}</{0}>".format(tag_name, func(name)) 
     return func_wrapper 
    return tags_decorator 

@tags("p") 
def get_text(name): 
    return "Hello "+name 

print get_text("John") 

मुझे ठीक कर लें मैं गलत हूँ लेकिन यह मेरी समझ है:

क्या बहुत ज्यादा मुझे confuses निम्नलिखित कोड है।

  • सजावटी डिफ़ॉल्ट फ़ंक्शन नाम के बजाय टैग स्ट्रिंग "पी" स्वीकार करता है। और बदले में फ़ंक्शन tags_decorator मानता है कि जिस पैरामीटर को पारित किया जाएगा वह सजाया जा रहा है, get_text

मेरे लिए "गैर-सजावटी" रूप में कोड के समकक्ष ब्लॉक को देखने में मददगार हो सकता है, लेकिन ऐसा लगता है कि यह मेरे सिर को लपेटने के लिए प्रतीत नहीं होता है। मैं यह भी समझ नहीं पा रहा हूं कि क्यों tags_decorator और func_wrapper दोनों लौट आए हैं। यदि सजावट करने वाले को get_text को लपेटने के लिए केवल 1 फ़ंक्शन वापस करने की आवश्यकता होती है तो दो अलग-अलग कार्यों को वापस करने का उद्देश्य क्या है।

एक साइड नोट के रूप में, यह वास्तव में निम्न पर आता है।

  • क्या यह ब्लॉक 3 कार्यों के सेट से कम कुछ के लिए सरलीकृत किया जा सकता है?
  • सजावटी कोड को सरल बनाने के लिए 1 से अधिक तर्क स्वीकार कर सकते हैं?

उत्तर

7

सीमाओं के भीतर, @ के बाद सब कुछ उपज एक डेकोरेटर को मार डाला जाता है।अपने पहले उदाहरण में, क्या इस प्रकार के बाद @ सिर्फ एक नाम है:

@p_decorate 

तो अजगर p_decorate ऊपर लग रहा है और एक तर्क के रूप सजाया समारोह के साथ यह कहता है:

get_text = p_decorate(get_text) 

(थोड़ा oversimplified, get_text प्रारंभ में मूल कार्य के लिए बाध्य नहीं है, लेकिन आपको पहले से ही मिल गया है)।

@tags("p") 

तो अजगर tags("p") का उपयोग करता डेकोरेटर को खोजने के लिए:

अपने दूसरे उदाहरण में, डेकोरेटर अभिव्यक्ति यह एक फोन भी शामिल है एक छोटे से अधिक शामिल है। अंत में यह है कि क्या उसके बाद क्रियान्वित किया जाता है:

get_text = tags("p")(get_text) 

उत्पादन tags("p") की डेकोरेटर यहाँ है! मैं tags स्वयं को एक सजावटी फैक्टरी पर कॉल करता हूं, यह कॉल करने पर सजावट का उत्पादन करता है। जब आप tags() पर कॉल करते हैं, तो यह tags_decorator() देता है। यह असली सजावटकर्ता है।

इसके बजाय आप डेकोरेटर समारोह को दूर कर सकता है और "p" मूल्य हार्डकोड और कहा कि सीधे का उपयोग करें:

def tags_decorator_p(func): 
    def func_wrapper(name): 
     return "<{0}>{1}</{0}>".format("p", func(name)) 
    return func_wrapper 

@tags_decorator_p 
def get_text(name): 
    # ... 

लेकिन फिर आप tags() को तर्क के प्रत्येक संभव मूल्य के लिए अलग सज्जाकार बनाने के लिए होगा। यह एक सजावटी कारखाने का मूल्य है, आप सजावटी को पैरामीटर जोड़ना चाहते हैं और यह बदल सकते हैं कि आपका फ़ंक्शन कैसे सजाया गया है।

एक सजावट फैक्टरी कोई भी तर्क ले सकता है; यह सिर्फ एक समारोह है जिसे आप एक सजावटी बनाने के लिए बुलाते हैं। सजावटी स्वयं केवल एक तर्क स्वीकार कर सकता है, फंक्शन-टू-सजाने।

मैंने कहा, किसी कारण के लिए मेरे उत्तर की शुरुआत में सीमाओं के भीतर; @ के बाद अभिव्यक्ति के लिए वाक्यविन्यास केवल एक बिंदीदार नाम (foo.bar.baz, इसलिए विशेषता पहुंच) और एक कॉल ((arg1, arg2, keyword=arg3)) की अनुमति देता है। reference documentation देखें। मूल PEP 318 राज्यों:

डेकोरेटर बयान क्या इसे स्वीकार कर सकते में सीमित है - मनमाना भाव काम नहीं करेगा। गिटो ने इसे आंत महसूस करने के कारण पसंद किया [17]।

+0

धन्यवाद। और मैंने आपकी प्रतिक्रिया के बाद एक छोटा सा संपादन किया। फ़ंक्शंस के इन सेट वास्तव में 2 फ़ंक्शंस क्यों लौटाते हैं और 1 नहीं? – Max

+1

@ मैक्स: मेरा नवीनतम संपादन देखें। एक सजावटी (सजावटी कारखाने द्वारा उत्पादित) है, दूसरा मूल कार्य को बदलने वाले रैपर है, सजावट का परिणाम। –

+0

अब मैं समझता हूं, 2 फ़ंक्शन कॉल का उद्देश्य। मैं अपने अंतिम रैपर को और निर्दिष्ट करने के लिए सजावटी कारखाने के साथ एक विशिष्ट सजावटी बनाने में सक्षम हूं। – Max

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