Hoe opent u een bestand met de openstaande verklaring

Ik kijk naar hoe u bestandsinvoer en uitvoer in Python kunt uitvoeren. Ik heb de volgende code geschreven om een ​​lijst met namen (één per regel) uit een bestand in een ander bestand te lezen tijdens het controleren van een naam tegen de namen in het bestand en het toevoegen van tekst aan de gebeurtenissen in het bestand. De code werkt. Kan het beter worden gedaan?

Ik wilde de with open(...verklaring voor zowel invoer- als uitvoerbestanden gebruiken, maar kan niet zien hoe ze in hetzelfde blok kunnen zijn, wat zou ik moeten opslaan de namen op een tijdelijke locatie.

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')

Antwoord 1, Autoriteit 100%

Python maakt het mogelijk om meerdere open()uitspraken in een enkele withte plaatsen. Je hebt ze gekozen. Uw code zou dan zijn:

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')

En nee, je wint niets door een expliciete returnaan het einde van je functie te plaatsen. U kunt returngebruiken om eerder af te sluiten, maar u had het aan het einde, en de functie zal zonder dit afsluiten. (Natuurlijk gebruik je bij functies die een waarde retourneren de returnom de waarde op te geven die moet worden geretourneerd.)

Het gebruik van meerdere open()-items met withwerd niet ondersteund in Python 2.5 toen de with-instructie werd geïntroduceerd, of in Python 2.6, maar het wordt ondersteund in Python 2.7 en Python 3.1 of nieuwer.

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

Als je code schrijft die moet worden uitgevoerd in Python 2.5, 2.6 of 3.0, nest dan de with-instructies zoals de andere antwoorden suggereerden of gebruik contextlib.nested.


Antwoord 2, autoriteit 10%

Gebruik op deze manier geneste blokken,

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

Antwoord 3, Autoriteit 4%

U kunt uw met blokken nestelen. Zoals dit:

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)

Dit is beter dan uw versie omdat u garandeert dat outfileis gesloten, zelfs als uw code uitzonderingen tegenkomt. Natuurlijk zou je dat kunnen doen met het proberen / eindelijk, maar withis de juiste manier om dit te doen.

Of, zoals ik zojuist heb geleerd, kunt u meerdere contextmanagers hebben in een verklaring als beschreven door @steveha . Dat lijkt mij een betere optie te zijn dan nestelen.

En voor uw laatste kleine vraag, dient het rendement geen echt doel. Ik zou het verwijderen.


Antwoord 4

Misschien wilt u mogelijk een variabele hoeveelheid bestanden openen en elk hetzelfde behandelen, kunt u dit doen met 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())                   

Other episodes