2013-01-06 55 views
8

उदाहरण चर के लिए मैं Contextmanager का उपयोग कैसे करूं? जैसे मान लें कि मुझे कुछ Connection कक्षा मिली है, जिसे विनाश पर बंद किया जाना चाहिए। अगर मैं इसे कॉन्टेक्स्ट मैनेजर के रूप में कार्यान्वित करना चाहता था तो मैं कर सकता था।उदाहरण चर के लिए संदर्भ प्रबंधक का उपयोग कैसे करें

with Connection() as c: 
    c.write('FOO') 
    c.ask('BAR?') 

और यह स्वचालित रूप से विनाश पर बंद हो जाएगा। लेकिन अगर मैं इसे किसी अन्य वर्ग के __init__ में उपयोग करना चाहता था, तो क्या होगा निम्नलिखित उदाहरण की तरह?

class Device(object): 
    def __init__(self): 
     self.connection = Connection() # Must be closed on destruction. 

मैं इसे कन्स्ट्रक्टर के बाहर निकलने के लिए बंद नहीं करना चाहता, यह वस्तु नष्ट होने पर मरनी चाहिए। मैं __del__ का उपयोग कर सकता हूं लेकिन इसका डाउनसाइड्स है। सी ++ में आरएआईआई में इस्तेमाल होने के कारण यह मुझे परेशान करता है।

तो इस मामले में ऐसा करने का सबसे अच्छा तरीका क्या है?

+2

ऑब्जेक्ट विनाश का समय किसी भी चीज़ के लिए सही समय नहीं है, खासकर संसाधन प्रबंधन के लिए नहीं। भूल जाओ कि कचरा संग्रह जैसी चीज है और सभी वस्तुओं को अनिश्चित काल तक जीते हैं। – delnan

उत्तर

6

आपको अपने Device.close() विधि में self.connection.close का आह्वान करना चाहिए, और उसके बाद संदर्भ प्रोग्राम के साथ, शायद अपने प्रोग्राम में ठीक से लागू होने की व्यवस्था करें।

__del__ कभी इसके लायक नहीं है।

1
from contextlib import contextmanager 

@contextmanager 
def connection(): 
    conn = Conn() 
    try: 
     yield conn 
    finally: 
     conn.close() 

class Conn(object): 
    def close(self): 
     print('Closing') 

class Device(object): 
    def __init__(self, conn): 
     self.conn = Conn() 

with connection() as conn: 
    d = Device(conn)