2016-02-10 8 views
7

में कक्षाओं के साथ काम करते हैं मैंने समझने की कोशिश की है कि कक्षा के लिए एक निश्चित सिंगलटन सजावट कार्यान्वयन कैसे किया जाता है, लेकिन मुझे केवल भ्रमित हो गया।कैसे सजावटी पाइथन

def singleton(cls): 
    instance = None 

    @functools.wraps(cls) 
    def inner(*args, **kwargs): 
     nonlocal instance 
     if instance is None: 
      instance = cls(*args, **kwargs) 
     return instance 
    return inner 

@deco, cls = deco(cls) के लिए एक syntatic चीनी है इस कोड में ऐसा है, जब हम अपने cls वर्ग को परिभाषित करते हैं और इस singleton डेकोरेटर के साथ लपेट, cls नहीं एक वर्ग अब हो जाएगा:

कोड यह , लेकिन एक समारोह। पाइथन गतिशील रूप से खोजता है कि कौन से ऑब्जेक्ट वेरिएबल हैं, इसलिए बाद में हम अपनी कक्षा का उदाहरण बनाने का प्रयास करते हैं, और कोड की यह पंक्ति instance = cls(*args, **kwargs) चलाती है, क्या हम अनंत रिकर्सन में नहीं जाएंगे? cls इस समय एक कक्षा नहीं है, यह एक कार्य है, इसलिए इसे खुद को कॉल करना चाहिए, रिकर्सन में जाना।

लेकिन यह ठीक काम करता है। एक सिंगलेटोन बनाया गया है और कोई पुनरावर्तन नहीं होता है। यह कैसे काम करता है?

उत्तर

4

फ़ंक्शन inner स्थानीय चर cls पर बंद है।

cls कक्षा का संदर्भ है। यह किसी और चीज के लिए कभी भी रिबाउंड नहीं होता है।

डेकोरेटर एक समारोह है कि एक उदाहरण देता है देता है, लेकिन यह प्रभावित नहीं करता है क्या आंतरिक cls चर

3

cls सजावट में पास की गई मूल कक्षा का संदर्भ है। यह उस सजावट को बरकरार रखता है जब सजावटी को बुलाया जाता था। सजावट द्वारा लौटाए गए समारोह में इसका मूल्य "फंस गया" है; अस्पष्ट कारणों से, इसे बंद कहा जाता है। अधिकांश भाषाएं जिनमें प्रथम श्रेणी के ऑब्जेक्ट्स हैं, इस क्षमता में हैं।

2
def singleton(cls): 
    instance = None 

    @functools.wraps(cls) 
    def inner(*args, **kwargs): 
     nonlocal instance 
     if instance is None: 
      instance = cls(*args, **kwargs) 
      print cls 
     return instance 
    return inner 

@singleton 
class TryMe(object): 
    pass 

m = TryMe() 
print m 

को संदर्भित करता है आप मिल जाएगा:

<class '__main__.TryMe'> 
<__main__.TryMe object at 0x10231c9d0> 
संबंधित मुद्दे