En Python, si vous ouvrez un fichier sans appeler close()
, ou fermez le fichier sans utiliser try
- finally
ou l' with
instruction " ", est-ce un problème? Ou est-il suffisant, en tant que pratique de codage, de s'appuyer sur le garbage collection Python pour fermer tous les fichiers? Par exemple, si on fait ça:
for line in open("filename"):
# ... do stuff ...
... est-ce un problème parce que le fichier ne peut jamais être fermé et qu'une exception pourrait se produire et empêcher sa fermeture? Ou sera-t-il définitivement fermé à la fin de la for
déclaration parce que le dossier sort du cadre?
python
file
garbage-collection
user553702
la source
la source
for
bloc. Son nombre de références ira à zéro, ce qui le fermera automatiquement, mais seules les fonctions, classes et modules définissent des portées en Python, pas d'autres instructions composées.for
blocs et les fonctions / classes / modules. C'est beaucoup plus simple que cela: les objets n'ont pas de portées, seuls les noms en ont. Il n'y a pas de nom qui fait référence à cet objet, donc il n'y a rien ici pour rester dans la portée ou sortir de la portée.for
boucle et mentionne que le fichier est fermé pour une raison entièrement différente. Cela n'entre pas dans les portées en Python, car ce n'est pas pertinent ici.Réponses:
Dans votre exemple, la fermeture du fichier n'est pas garantie avant la fermeture de l'interpréteur. Dans les versions actuelles de CPython, le fichier sera fermé à la fin de la boucle for car CPython utilise le comptage de références comme principal mécanisme de garbage collection, mais c'est un détail d'implémentation, pas une fonctionnalité du langage. Les autres implémentations de Python ne sont pas garanties de fonctionner de cette façon. Par exemple, IronPython, PyPy et Jython n'utilisent pas de comptage de références et ne fermeront donc pas le fichier à la fin de la boucle.
C'est une mauvaise pratique de s'appuyer sur l'implémentation du garbage collection de CPython car cela rend votre code moins portable. Vous n'aurez peut-être pas de fuites de ressources si vous utilisez CPython, mais si vous passez un jour à une implémentation Python qui n'utilise pas de comptage de références, vous devrez parcourir tout votre code et vous assurer que tous vos fichiers sont correctement fermés.
Pour votre exemple, utilisez:
la source
with open() as f
ferme- t-elle automatiquement le fichier une fois terminé?with
déclaration fournit, mais bien sûr, pour que cette magie fonctionne, l'objet doit avoir les méthodes spéciales__enter__
et__exit__
, dans ce dernier, l'objet doit faire leclose
et tout autre nettoyage qui doit être fait au fin de lawith
déclaration ...Certains Pythons fermeront automatiquement les fichiers lorsqu'ils ne sont plus référencés, tandis que d'autres ne le feront pas et c'est à l'O / S de fermer les fichiers lorsque l'interpréteur Python se termine.
Même pour les Pythons qui fermeront les fichiers pour vous, le timing n'est pas garanti: cela pourrait être immédiat, ou cela pourrait être quelques secondes / minutes / heures / jours plus tard.
Ainsi, même si vous ne rencontrez pas de problèmes avec le Python que vous utilisez, ce n'est certainement pas une bonne pratique de laisser vos fichiers ouverts. En fait, dans cpython 3, vous recevrez maintenant des avertissements indiquant que le système devait fermer des fichiers pour vous si vous ne le faisiez pas.
Morale: nettoyez après vous. :)
la source
Bien qu'il soit tout à fait sûr d'utiliser une telle construction dans ce cas particulier, il existe quelques mises en garde pour généraliser une telle pratique:
la source
Le fichier est récupéré et donc fermé. Le GC détermine quand il est fermé, pas vous. De toute évidence, ce n'est pas une pratique recommandée car vous pourriez atteindre la limite de descripteur de fichier ouvert si vous ne fermez pas les fichiers dès que vous avez fini de les utiliser. Et si dans votre
for
boucle, vous ouvrez plus de fichiers et les laissez en attente?la source
for
instruction - vous n'aurez pas à attendre la prochaine exécution de garbage collection.Salut Il est très important de fermer votre descripteur de fichier dans la situation où vous allez utiliser son contenu dans le même script python. Aujourd'hui, je me rends compte après un débogage si long. La raison en est que le contenu ne sera modifié / supprimé / enregistré qu'après la fermeture du descripteur de fichier et les modifications sont affectées au fichier!
Supposons donc que vous ayez une situation où vous écrivez du contenu dans un nouveau fichier, puis sans fermer fd, vous utilisez ce fichier (et non fd) dans une autre commande shell qui lit son contenu. Dans cette situation, vous n'obtiendrez pas le contenu de la commande shell comme prévu et si vous essayez de déboguer, vous ne pouvez pas trouver facilement le bogue. vous pouvez également en lire plus dans mon article de blog http://magnificentzps.blogspot.in/2014/04/importance-of-closing-file-descriptor.html
la source
Pendant le processus d'E / S, les données sont mises en mémoire tampon: cela signifie qu'elles sont conservées dans un emplacement temporaire avant d'être écrites dans le fichier.
Python ne vide pas la mémoire tampon, c'est-à-dire n'écrit pas les données dans le fichier, tant qu'il n'est pas certain que vous avez fini d'écrire. Une façon de procéder consiste à fermer le fichier.
Si vous écrivez dans un fichier sans fermer, les données ne parviendront pas au fichier cible.
la source