Itérer sur un fichier en utilisant Python
j'ai un problème pour comprendre l'itération sur un fichier, Ici je vais sur ce que je tape sur l'interprète et le résultat:
>>> f = open('baby1990.html', 'rU')
>>> for line in f.readlines():
>>> print(line)
>>> ...
>>> ... all the lines from the file appear here
>>> ...
quand j'essaie d'itérer à nouveau sur le même fichier ouvert je n'ai rien!!!!
>>> f = open('baby1990.html', 'rU')
>>> for line in f.readlines():
>>> print(line)
>>>
>>>
il n'y a pas de sortie du tout, pour résoudre cela je dois fermer() le fichier puis l'ouvrir à nouveau pour la lecture!! C'est qu'un comportement normal?
4 réponses
Oui, c'est un comportement normal. Vous lisez essentiellement à la fin du fichier la première fois (vous pouvez en quelque sorte l'imaginer comme lisant une bande), de sorte que vous ne pouvez plus lire à partir de celui-ci à moins que vous ne le réinitialisez, en utilisant l'un ou l'autre f.seek(0)
pour repositionner le début du fichier, ou le fermer puis ouvrir à nouveau qui commencera à partir du début du fichier.
Si vous préférez, vous pouvez utiliser le with
syntaxe à la place qui fermera automatiquement le fichier pour vous.
e.g.,
with open('baby1990.html', 'rU') as f:
for line in f:
print line
une fois que ce bloc est terminé, le fichier est automatiquement fermé pour vous, vous pouvez donc exécuter ce bloc de façon répétée sans fermer explicitement le fichier vous-même et lire le fichier de cette façon à nouveau.
comme l'objet file lit le fichier, il utilise un pointeur pour garder la trace de l'endroit où il se trouve. Si vous lisez la partie du fichier, puis y revenir plus tard, il reprendra là où vous l'avez laissé. Si vous lisez l'ensemble du dossier et revenir vers le même fichier objet, c'est comme lire un fichier vide parce que le pointeur est à la fin du fichier et il n'y a plus rien à lire. Vous pouvez utiliser file.tell()
voir où dans le fichier, le pointeur est et file.seek
pour mettre le pointeur. Pour exemple:
>>> file = open('myfile.txt')
>>> file.tell()
0
>>> file.readline()
'one\n'
>>> file.tell()
4L
>>> file.readline()
'2\n'
>>> file.tell()
6L
>>> file.seek(4)
>>> file.readline()
'2\n'
aussi, vous devriez savoir que file.readlines()
lit l'ensemble du fichier et le stocke sous forme de liste. C'est utile à savoir car vous pouvez remplacer:
for line in file.readlines():
#do stuff
file.seek(0)
for line in file.readlines():
#do more stuff
avec:
lines = file.readlines()
for each_line in lines:
#do stuff
for each_line in lines:
#do more stuff
vous pouvez aussi itérer sur un fichier, une ligne à la fois, sans garder le fichier entier en mémoire (cela peut être très utile pour de très gros fichiers) en faisant:
for line in file:
#do stuff
l'objet file est un tampon. Lorsque vous lisez à partir du tampon, la partie que vous lisez est consommée (la position de lecture est déplacée vers l'avant). Quand vous lisez tout le fichier, la position de lecture est à L'EOF, donc il ne retourne rien parce qu'il ne reste rien à lire.
Si vous devez, pour une raison quelconque, la réinitialisation de la position de lecture sur un fichier objet, vous pouvez le faire:
f.seek(0)
bien sûr.
Ce qui est normal et sain d'esprit de comportement.
Au lieu de fermer et de rouvrir, vous pourriez rewind
le fichier.