Je regarde comment faire l'entrée et la sortie de fichier en Python. J'ai écrit le code suivant pour lire une liste de noms (un par ligne) d'un fichier dans un autre fichier tout en comparant un nom aux noms du fichier et en ajoutant du texte aux occurrences du fichier. Le code fonctionne. Pourrait-il être mieux fait?
J'aurais voulu utiliser l'instruction with open(...
pour les fichiers d'entrée et de sortie, mais je ne voyais pas comment ils pourraient être dans le même bloc, ce qui signifierait que je devrais stocker les noms dans un emplacement temporaire.
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')
Python permet de mettre plusieurs instructions open()
dans une seule with
. Vous les séparez par des virgules. Votre code serait alors:
_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')
_
Et non, vous ne gagnez rien en mettant un return
explicite à la fin de votre fonction. Vous pouvez utiliser return
pour quitter tôt, mais vous l’aviez à la fin et la fonction se fermerait sans elle. (Bien sûr, avec les fonctions qui renvoient une valeur, vous utilisez le return
pour spécifier la valeur à renvoyer.)
L'utilisation de plusieurs éléments open()
avec with
n'était pas prise en charge dans Python 2.5 lorsque l'instruction with
ou dans Python 2.6 a été introduite. est supporté dans Python 2.7 et Python 3.1 ou plus récent.
http://docs.python.org/reference/compound_stmts.html#the-with-statementhttp://docs.python.org/release/3.1/reference/compound_stmts. html # the-with-statement
Si vous écrivez du code qui doit être exécuté dans Python 2.5, 2.6 ou 3.0, imbriquez les instructions with
comme les autres réponses suggérées ou utilisez contextlib.nested
.
Utilisez des blocs imbriqués comme celui-ci,
with open(newfile, 'w') as outfile:
with open(oldfile, 'r', encoding='utf-8') as infile:
# your logic goes right here
Vous pouvez faire votre nid avec des blocs. Comme ça:
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)
C'est mieux que votre version car vous garantissez que outfile
sera fermé même si votre code rencontre des exceptions. Évidemment, vous pouvez le faire avec try/finally, mais with
est la bonne façon de le faire.
Ou, comme je viens de l’apprendre, vous pouvez avoir plusieurs gestionnaires de contexte dans une instruction with telle que décrite par @steveha . Cela me semble être une meilleure option que la nidification.
Et pour votre dernière question mineure, le retour ne sert à rien. Je l'enlèverais.
Parfois, vous voudrez peut-être ouvrir un nombre variable de fichiers et les traiter de la même façon, vous pouvez le faire avec 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())