स्टेटमेंट के साथ ओपन का उपयोग करके फाइल कैसे खोलें


200

मैं देख रहा हूँ कि पायथन में फ़ाइल इनपुट और आउटपुट कैसे करें। मैंने फ़ाइल में नामों के विरुद्ध नाम की जाँच करते हुए और फ़ाइल में होने वाली घटनाओं के पाठ को जोड़ते हुए एक फ़ाइल से दूसरी फ़ाइल में नामों की सूची (एक पंक्ति में) पढ़ने के लिए निम्नलिखित कोड लिखा है। कोड काम करता है। क्या यह बेहतर किया जा सकता है?

मैं with open(...इनपुट और आउटपुट फाइल दोनों के लिए स्टेटमेंट का उपयोग करना चाहता था, लेकिन यह नहीं देख सकता कि वे एक ही ब्लॉक अर्थ में कैसे हो सकते हैं, मुझे नाम को एक अस्थायी स्थान पर संग्रहीत करने की आवश्यकता होगी।

def filter(txt, oldfile, newfile):
    '''\
    Read a list of names from a file line by line into an output file.
    If a line begins with a particular name, insert a string of text
    after the name before appending the line to the output file.
    '''

    outfile = open(newfile, 'w')
    with open(oldfile, 'r', encoding='utf-8') as infile:
        for line in infile:
            if line.startswith(txt):
                line = line[0:len(txt)] + ' - Truly a great person!\n'
            outfile.write(line)

    outfile.close()
    return # Do I gain anything by including this?

# input the name you want to check against
text = input('Please enter the name of a great person: ')    
letsgo = filter(text,'Spanish', 'Spanish2')

"का अर्थ है कि मुझे अस्थायी स्थान पर नामों को संग्रहीत करने की आवश्यकता होगी"? क्या आप इसका मतलब समझा सकते हैं?
S.Lott

4
ध्यान दें कि filter()है एक अंतर्निहित समारोह और इसलिए आप शायद अपने समारोह के लिए एक अलग नाम का चयन करना चाहिए।
टॉम

2
@ क्या नाम स्थान में कोई फ़ंक्शन अंतर्निहित फ़ंक्शन को ओवरराइड करता है?
19

2
@UpTide: हाँ, अजगर LEGB क्रम में चल रही है - स्थानीय, संलग्न करते हुए, ग्लोबल, निर्मित (देखें stackoverflow.com/questions/291978/... )। इसलिए, यदि आप एक वैश्विक कार्य करते हैं ( filter()), तो यह बिल्ट-इनfilter()
टॉम

जवाबों:


308

अजगर open()एक में कई बयान डालने की अनुमति देता है with। आप उन्हें अलग करते हैं। आपका कोड तब होगा:

def filter(txt, oldfile, newfile):
    '''\
    Read a list of names from a file line by line into an output file.
    If a line begins with a particular name, insert a string of text
    after the name before appending the line to the output file.
    '''

    with open(newfile, 'w') as outfile, open(oldfile, 'r', encoding='utf-8') as infile:
        for line in infile:
            if line.startswith(txt):
                line = line[0:len(txt)] + ' - Truly a great person!\n'
            outfile.write(line)

# input the name you want to check against
text = input('Please enter the name of a great person: ')    
letsgo = filter(text,'Spanish', 'Spanish2')

और नहीं, आप returnअपने फ़ंक्शन के अंत में एक स्पष्ट डालकर कुछ भी हासिल नहीं करते हैं। आप returnजल्दी बाहर निकलने के लिए उपयोग कर सकते हैं , लेकिन आपके पास यह अंत में था, और फ़ंक्शन इसके बिना बाहर निकल जाएगा। (निश्चित रूप से मानों को लौटाने वाले कार्यों के लिए, आप returnमान को लौटने के लिए निर्दिष्ट करने के लिए उपयोग करते हैं।)

जब बयान पेश किया गया था, या पायथन 2.6 में पायथन 2.5 के open()साथ कई वस्तुओं का उपयोग withनहीं किया withगया था, लेकिन यह पायथन 2.7 और पायथन 3.1 या नए में समर्थित है।

http://docs.python.org/reference/compound_stmts.html#the-with-statement http://docs.python.org/release/3.1/reference/compound_stmts.html#the-with-statement

यदि आप ऐसा कोड लिख रहे हैं जो पायथन 2.5, 2.6 या 3.0 में चलना चाहिए, तो withदिए गए अन्य उत्तरों के रूप में बयानों का उपयोग करें contextlib.nested


28

इस तरह नेस्टेड ब्लॉक्स का उपयोग करें,

with open(newfile, 'w') as outfile:
    with open(oldfile, 'r', encoding='utf-8') as infile:
        # your logic goes right here

12

आप अपने ब्लॉक के साथ घोंसला बना सकते हैं। ऐशे ही:

with open(newfile, 'w') as outfile:
    with open(oldfile, 'r', encoding='utf-8') as infile:
        for line in infile:
            if line.startswith(txt):
                line = line[0:len(txt)] + ' - Truly a great person!\n'
            outfile.write(line)

यह आपके संस्करण से बेहतर है क्योंकि आप गारंटी देते हैं कि outfileआपका कोड अपवाद होने पर भी बंद रहेगा। जाहिर है कि आप कोशिश कर सकते हैं / आखिरकार, लेकिनwith ऐसा करने का सही तरीका है।

या, जैसा कि मैंने अभी सीखा है, आपके पास @steveha द्वारा बताए गए विवरण के साथ कई संदर्भ प्रबंधक हो सकते हैं । ऐसा लगता है कि मुझे घोंसला बनाने से बेहतर विकल्प है।

और आपके अंतिम मामूली प्रश्न के लिए, रिटर्न कोई वास्तविक उद्देश्य नहीं है। मैं इसे हटा दूंगा।


बहुत बहुत धन्यवाद। मैं इसे आज़माऊँगा और आपके जवाब को स्वीकार करूँगा / अगर मुझे यह काम करने के लिए मिलता है।
बजे डिसमनी

एक बार फिर धन्यवाद। मुझे स्वीकार करने से पहले सात मिनट तक इंतजार करना होगा।
१५:१५ बजे डिसमनी

7
@Disnami सुनिश्चित करें कि आप सही उत्तर को स्वीकार करते हैं (और यह एक नहीं है!) ;-)
डेविड हेफ़रनन

1

कभी-कभी, आप फ़ाइलों की एक परिवर्तनीय राशि खोलना चाहते हैं और हर एक के साथ एक जैसा व्यवहार कर सकते हैं contextlib

from contextlib import ExitStack
filenames = [file1.txt, file2.txt, file3.txt]

with open('outfile.txt', 'a') as outfile:
    with ExitStack() as stack:
        file_pointers = [stack.enter_context(open(file, 'r')) for file in filenames]                
            for fp in file_pointers:
                outfile.write(fp.read())                   
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.