2012-03-15 11 views
24

कुछ कोड:क्या मुझे StringIO.close() करना है?

import cStringIO 

def f(): 
    buffer = cStringIO.StringIO() 
    buffer.write('something') 
    return buffer.getvalue() 

documentation का कहना है:

StringIO.close(): स्मृति बफर मुफ्त। एक बंद StringIO ऑब्जेक्ट के साथ संचालन करने का प्रयास करने से ValueError बढ़ेगा।

क्या मुझे buffer.close() करना है, या जब यह बफर गुंजाइश से बाहर हो जाता है और कचरा इकट्ठा होता है तो यह स्वचालित रूप से हो जाएगा?

अद्यतन:

मैं एक परीक्षण किया:

import StringIO, weakref 

def handler(ref): 
    print 'Buffer died!' 

def f(): 
    buffer = StringIO.StringIO() 
    ref = weakref.ref(buffer, handler) 
    buffer.write('something') 
    return buffer.getvalue() 

print 'before f()' 
f() 
print 'after f()' 

परिणाम:

[email protected]:~/projects$ python test.py 
before f() 
Buffer died! 
after f() 
[email protected]:~/projects$ 
+0

क्यों न केवल एक नग्न f() के बजाय f() मुद्रित करें? – mpag

उत्तर

12

आम तौर पर close() पर कॉल करना बेहतर है या with कथन का उपयोग करें, क्योंकि विशेष परिस्थितियों में कुछ अप्रत्याशित व्यवहार हो सकते हैं। उदाहरण के लिए, एक्सपैट- IncrementalParser एक फ़ाइल को बंद होने की अपेक्षा करता है, या यह कुछ दुर्लभ परिस्थितियों में एक टाइमआउट होने तक पार्स किए गए एक्सएमएल की अंतिम टिड्बी वापस नहीं करेगा।

लेकिन with -statement है, जो आप के लिए बंद संभालती के लिए, आप के रूप में आईवीसी की टिप्पणी में कहा गया है, io -Modules से StringIO वर्ग का उपयोग करने के लिए है।

यह कुछ विरासत सैक्स-पार्सर स्क्रिप्ट में एक प्रमुख सिरदर्द था जिसे हमने स्ट्रिंगियो मैन्युअल रूप से बंद करके हल किया था।

"आउट-ऑफ-स्कोप" बंद नहीं हुआ। यह बस टाइमआउट सीमा के लिए इंतजार कर रहा था।

+14

ध्यान दें कि StringIO और cStringIO Py2 में संदर्भ प्रबंधक प्रोटोकॉल लागू नहीं है सिवाय - हां, तो एक 'with' बयान आप' contextlib.closing साथ क्या करने की जरूरत (StringIO()) बफर के रूप में में इसका उपयोग करना: '। Py3 के 'io.StringIO', दूसरे हाथ पर, * * एक' with' बयान सीधे में इस्तेमाल किया जा सकता है। – lvc

+3

'io.StringIO' संदर्भ प्रबंधक प्रोटोकॉल को लागू करता है, लेकिन नहीं पहले 2.6 देखें: http: //docs.python।संगठन/रिलीज/2.6.7/लाइब्रेरी/io.html हाइलाइट = io.stringio # io.IOBase' –

+2

आह, मुझे एहसास नहीं हुआ था कि 'io' मॉड्यूल बहुत दूर था। सूचक के लिए धन्यवाद। हालांकि, यह बनी हुई है कि OP में उपयोग किए गए 'StringIO.StringIO' और 'cStringIO.StringIO' मॉड्यूल नहीं हैं। मैं वास्तव में थोड़ा आश्चर्यचकित हूं कि उन्हें 2.6/2.7 में बहिष्कृत के रूप में चिह्नित नहीं किया गया है, और 2.7 दस्तावेज़ों में यह भी सामान्य नोट नहीं है कि "ये अब 3.x में मौजूद नहीं हैं"। – lvc

8

StringIO.close() केवल दिनचर्या है कि लेने के लिए एक सुविधा है एक फ़ाइल की तरह है और अंत में करने का प्रयास उन्हें बंद करो। ऐसा करने की कोई ज़रूरत नहीं है।

+1

यह एक सुविधा नहीं बल्कि एक आवश्यकता है। यह कोड बंद कर देता है कि फाइल जैसी वस्तु टूट जाएगा बिना। –

+3

@ मैक्सिम: यह कोड के लिए एक आवश्यकता है। यह ग्राहक के लिए एक सुविधा है। –

11
स्रोत से

:

class StringIO: 
    ... 
    def close(self): 
     """Free the memory buffer. 
     """ 
     if not self.closed: 
      self.closed = True 
      del self.buf, self.pos 

तो StringIO.close सिर्फ स्मृति बफर StringIO.buf और StringIO.pos के लिए संदर्भ को हटाने को मुक्त कर देते। लेकिन अगर self कचरा इकट्ठा किया गया है, तो इसके गुण भी कचरा इकट्ठा किए जाएंगे, जिसमें StringIO.close के समान प्रभाव होगा।

3

मैं इसे संभाल करने के लिए एक try ब्लॉक का उपयोग बंद कर।

import cStringIO 

def f(): 
    buffer = cStringIO.StringIO() 
    try: 
     buffer.write('something') 
     return buffer.getvalue() 
    finally: 
     buffer.close() 
संबंधित मुद्दे