Comment ouvrir / fermer des fichiers en toute sécurité dans Python 2.4


86

J'écris actuellement un petit script à utiliser sur l'un de nos serveurs en utilisant Python. Le serveur n'a installé que Python 2.4.4.

Je n'ai pas commencé à utiliser Python avant la sortie de 2.5, donc je suis habitué au formulaire:

with open('file.txt', 'r') as f:
    # do stuff with f

Cependant, il n'y a pas de withdéclaration avant 2.5, et j'ai du mal à trouver des exemples sur la bonne façon de nettoyer manuellement un objet fichier.

Quelle est la meilleure pratique pour se débarrasser des objets fichier en toute sécurité lors de l'utilisation d'anciennes versions de python?

Réponses:


139

Voir docs.python.org :

Lorsque vous avez terminé avec un fichier, appelez f.close () pour le fermer et libérer toutes les ressources système occupées par le fichier ouvert. Après avoir appelé f.close (), les tentatives d'utilisation de l'objet fichier échoueront automatiquement.

Utilisez donc close()avec élégance try/finally:

f = open('file.txt', 'r')

try:
    # do stuff with f
finally:
    f.close()

Cela garantit que même si # do stuff with fdéclenche une exception, fsera toujours fermé correctement.

Notez que cela opendevrait apparaître en dehors du try. Si openlui-même déclenche une exception, le fichier n'a pas été ouvert et n'a pas besoin d'être fermé. De plus, si openlève une exception, son résultat n'est pas affecté fet c'est une erreur à appeler f.close().


Très simple, merci. Pour une raison quelconque, je m'attendais à avoir besoin de quelque chose de plus complexe.
TM.

16
En cas d' openéchec, une exception sera déclenchée avant même que le try/finallybloc ne soit entré. Donc closene sera pas appelé. (C'est pourquoi vous devriez appeler openavant le try.)
FogleBird

1
@TM J'ai ajouté une note sur la openlevée d'une exception.
Jon-Eric

4
C'est ce que la déclaration with traduit en coulisses.
Arlaharen

1
L'ouverture du fichier devrait avoir lieu pendant l'essai.
Anthony Rutledge

32

Dans la solution ci-dessus, répétée ici:

f = open('file.txt', 'r')

try:
    # do stuff with f
finally:
   f.close()

si quelque chose de mauvais se produit (on ne sait jamais ...) après l'ouverture du fichier avec succès et avant l'essai, le fichier ne sera pas fermé, donc une solution plus sûre est:

f = None
try:
    f = open('file.txt', 'r')

    # do stuff with f

finally:
    if f is not None:
       f.close()

En utilisant une instruction with open (...), peu importe comment le bloc with est terminé (même avec une exception), le fichier est fermé
darkgaze

@darkgaze with open(...)est certainement le meilleur choix en Python moderne.
mljrg

11

Pas besoin de fermer le fichier selon la documentation si vous utilisez avec:

Il est recommandé d'utiliser le mot-clé with pour traiter des objets fichier. Cela présente l'avantage que le fichier est correctement fermé une fois sa suite terminée, même si une exception est déclenchée en cours de route. C'est aussi beaucoup plus court que d'écrire des blocs try-finally équivalents:

>>> with open('workfile', 'r') as f:
...     read_data = f.read()
>>> f.closed
True

Plus d'informations ici: https://docs.python.org/2/tutorial/inputoutput.html#methods-of-file-objects


Ceci est à la fois correct et inconscient de la question.
Jon-Eric

-4

Voici un exemple donné qui donc comment utiliser openet "pythonclose

from sys import argv
script,filename=argv
txt=open(filename)
print "filename %r" %(filename)
print txt.read()
txt.close()
print "Change the file name"
file_again=raw_input('>')
print "New file name %r" %(file_again)
txt_again=open(file_again)
print txt_again.read()
txt_again.close()

Il est nécessaire de savoir combien de fois vous avez ouvert le fichier pour le fermer.


1
Si une exception est déclenchée après openmais avant close, le fichier ne sera pas correctement fermé en utilisant cette approche. L'utilisation de withou try/ finallyferme le fichier correctement même en présence d'exceptions.
Jon-Eric
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.