52 votes

Est-il nécessaire de fermer les fichiers qui n'ont pas de référence?

En tant que débutant complet au niveau de la programmation, je suis en train d'essayer de comprendre les concepts de base de l'ouverture et la fermeture des fichiers. Un exercice que je suis en train de faire est de créer un script qui me permet de copier le contenu d'un fichier à un autre.

in_file = open(from_file)
indata = in_file.read()

out_file = open(to_file, 'w')
out_file.write(indata)

out_file.close()
in_file.close()

J'ai essayé de raccourcir ce code, et en arrive à ceci:

indata = open(from_file).read()
open(to_file, 'w').write(indata)

Cela fonctionne et semble un peu plus efficace pour moi. Cependant, c'est aussi là que je m'embrouille. Je pense que j'ai laissé de côté les références à l'ouverture des fichiers; il n'était pas nécessaire pour le in_file et out_file variables. Cependant, ceci me laisse avec deux fichiers qui sont ouverts, mais n'ont rien en se référant à eux? Comment puis-je fermer ceux-ci, ou n'est-il pas besoin?

Toute aide qui jette une certaine lumière sur ce sujet est très apprécié.

57voto

RoadieRich Points 303

Le pythonic façon de traiter cette question est d'utiliser l' with gestionnaire de contexte:

with open(from_file) as in_file, open(to_file, 'w') as out_file:
    indata = in_file.read()
    out_file.write(indata)

Utilisé avec les fichiers comme ceci, with veillera à ce que tout le nécessaire de nettoyage est fait pour vous, même si read() ou write() de générer des erreurs.

38voto

alexis Points 10856

Vous avez demandé à propos de la "concepts de base", donc, nous allons jeter du haut: Lorsque vous ouvrez un fichier, votre programme accède à une ressource de système, c'est-à quelque chose en dehors du programme de l'espace mémoire. C'est un peu de la magie fournis par le système d'exploitation (un appel système, dans la terminologie Unix). Caché à l'intérieur du fichier de l'objet est une référence à un "descripteur de fichier", le réel OS ressource associée avec le fichier ouvert. Fermeture du fichier indique le système de libération de cette ressource.

Comme un système d'exploitation de ressources, le nombre de fichiers qu'un processus peut garder ouvert est limité: il y a Longtemps la limite de processus était d'environ 20 sur Unix. Droit maintenant, mes OS X boîte impose une limite de 256 ouvrir des fichiers (même si c'est une limite imposée, et peut être relevée). D'autres systèmes peuvent fixer des limites de quelques milliers, ou dans les dizaines de milliers (par utilisateur et non par le processus dans ce cas). Lorsque votre programme se termine, toutes les ressources sont automatiquement libérés. Donc, si votre programme s'ouvre en quelques fichiers, fait quelque chose avec eux et les sorties, vous pouvez être bâclée et vous ne saurez jamais la différence. Mais si votre programme sera l'ouverture de milliers de fichiers, que vous ferez bien de libérer les fichiers ouverts pour éviter de dépasser les OS des limites.

Il y a un autre avantage pour la fermeture des fichiers avant de votre processus de sorties: Si vous avez ouvert un fichier pour l'écriture, clôture, il sera le premier "vider sa mémoire tampon de sortie". Cela signifie que les bibliothèques d'e/s d'optimiser l'utilisation du disque par la collecte ("tampon") ce que vous écrivez, et de l'enregistrer sur le disque dans des lots. Si vous écrivez un texte dans un fichier et immédiatement essayer de les rouvrir et de les lire sans d'abord la fermeture de la sortie de la poignée, vous verrez que tout n'a pas été écrit. Aussi, si votre programme est fermé de façon trop brutale (avec un signal, ou parfois même à travers la sortie normale), la sortie peut jamais être rincés.

Il y a déjà beaucoup d'autres réponses sur la façon de libérer des fichiers, donc en voici une brève liste de démarches:

  1. Explicitement close(). (Note pour python débutants: N'oubliez pas les parenthèses! Mes élèves aiment écrire in_file.close, qui ne fait rien.)

  2. Recommandé: Implicitement, en ouvrant les fichiers avec l' with déclaration. L' close() méthode sera appelée lors de la fin de l' with bloc est atteint, même en cas d'arrêt anormal (à partir d'une exception).

    with open("data.txt") as in_file:
        data = in_file.read()
    
  3. Implicitement par le gestionnaire de référence ou garbage collector, si votre python moteur de l'implémente. Ce n'est pas recommandé, car il n'est pas entièrement portable; voir les autres réponses pour plus de détails. C'est pourquoi l' with énoncé a été ajouté à python.

  4. Implicitement, lorsque la fin de votre programme. Si un fichier est ouvert pour la sortie, ce qui peut exécuter un risque que le programme de la sortie avant que le tout a été vidé sur le disque.

36voto

MisterMiyagi Points 2734

La valeur par défaut de python interprète, Disponible, utilise le comptage de référence. Cela signifie qu'une fois il n'y a pas de références à un objet, il obtient le garbage collector, c'est à dire nettoyé.

Dans votre cas, faire

open(to_file, 'w').write(indata)

va créer un fichier objet pour to_file, mais de ne pas assigner à un nom - cela signifie qu'il n'y a aucune référence. Vous ne pouvez pas éventuellement manipuler l'objet après cette ligne.

Disponible cela permet de détecter et nettoyer l'objet après qu'il a été utilisé. Dans le cas d'un fichier, cela signifie la fermeture automatiquement. En principe, c'est très bien, et votre programme n'a pas de fuite de mémoire.

Le "problème" est ce mécanisme est un détail d'implémentation de le Disponible interprète. La langue standard explicitement donne aucune garantie!!!! Si vous utilisez un autre interprète comme pypy, la fermeture automatique des fichiers peut être retardée indéfiniment. Cela inclut d'autres implicite des actions telles que bouffées de chaleur écrit sur fermer.

Ce problème s'applique également à d'autres ressources, par exemple les sockets réseau. Il est de bonne pratique de toujours traiter explicitement de telles ressources externes. Depuis la version 2.6 de python, l' with déclaration rend cet élégant:

with open(to_file, 'w') as out_file:
    out_file.write(in_data)

TLDR: Il fonctionne, mais s'il vous plaît ne pas le faire.

7voto

Darrick Herwehe Points 2125

Les réponses sont absolument correctes lorsque l'on travaille en python. Vous devez utiliser l' with open() gestionnaire de contexte. C'est une grande fonctionnalité intégrée, et à l'aide de raccourci une commune de la tâche de programmation (ouverture et fermeture d'un fichier).

Cependant, puisque vous êtes un débutant et ne pas avoir accès à des gestionnaires de contexte et automatisé de comptage de référence pour l'ensemble de votre carrière, je vais répondre à la question à partir d'une programmation générale de position.

La première version de votre code est parfaitement bien. Vous ouvrez un fichier, enregistrez la référence, de lire le fichier, puis fermez-le. C'est la façon dont beaucoup de code est écrit lorsque la langue n'est pas un raccourci pour la tâche. La seule chose que je voudrais améliorer est de déplacer close() à où vous êtes ouverture et lecture du fichier. Une fois que vous ouvrez et lisez le fichier, vous avez le contenu dans la mémoire et n'a plus besoin du fichier à ouvrir.

in_file = open(from_file)
indata = in_file.read()
out_file.close() 

out_file = open(to_file, 'w')
out_file.write(indata)
in_file.close()

7voto

python Points 1241

Il est de bonne pratique d'utiliser l' with mot-clé lorsque vous traitez avec des objets de fichier. Ceci a l'avantage que le fichier est correctement fermé après sa gamme de finitions, même si une exception est levée sur le chemin. Il est également beaucoup plus courte que d'écrire l'équivalent essayez-enfin blocs:

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X