web-dev-qa-db-fra.com

Lire tout le fichier dans Python

Si vous lisez un fichier entier avec content = open('Path/to/file', 'r').read(), le descripteur de fichier reste-t-il ouvert jusqu'à la fin du script? Existe-t-il une méthode plus concise pour lire un fichier entier?

314
tMC

La réponse à cette question dépend un peu de l'implémentation Python particulière.

Pour comprendre ce dont il s'agit, portez une attention particulière à l'objet file actuel. Dans votre code, cet objet n'est mentionné qu'une fois, dans une expression, et devient inaccessible immédiatement après le retour de l'appel read().

Cela signifie que l'objet de fichier est un déchet. La seule question qui reste est "Quand le ramasse-miettes va-t-il collecter l'objet fichier?".

dans CPython, qui utilise un compteur de références, ce type de déchets est immédiatement détecté et il sera donc immédiatement collecté. Ce n'est généralement pas le cas d'autres implémentations python.

Une meilleure solution, pour vous assurer que le fichier est fermé, est la suivante:

with open('Path/to/file', 'r') as content_file:
    content = content_file.read()

qui fermera toujours le fichier immédiatement après la fin du bloc; même si une exception se produit.

Edit: Pour mettre un point plus fin sur elle:

Autre que file.__exit__(), qui est appelée "automatiquement" dans un paramètre de gestionnaire de contexte with, le seul autre moyen d'appeler automatiquement file.close() (autrement dit, autrement que de l'appeler explicitement vous-même), est via file.__del__(). Ceci nous amène à la question de savoir quand est-ce que __del__() est appelé?

Un programme correctement écrit ne peut pas supposer que les finaliseurs seront exécutés à un moment quelconque avant la fin du programme.

- https://devblogs.Microsoft.com/oldnewthing/20100809-00/?p=132

En particulier:

Les objets ne sont jamais explicitement détruits; Cependant, lorsqu'ils deviennent inaccessibles, ils peuvent être ramassés. Une implémentation est autorisée à différer ou à omettre totalement le garbage collection - la qualité de la mise en œuvre dépend de la manière dont la garbage collection est implémentée, aussi longtemps qu'aucun objet ne l'est collectés qui sont toujours accessibles.

[...]

CPython utilise actuellement un schéma de comptage de références avec détection (facultative) retardée des déchets liés cycliquement, qui collecte la plupart des objets dès qu'ils deviennent inaccessibles, mais il n'est pas garanti que les déchets contenant des références circulaires soient collectés.

- https://docs.python.org/3.5/reference/datamodel.html#objects-values-and-types

(Souligné par moi)

mais comme il est suggéré, d'autres implémentations peuvent avoir un autre comportement. Par exemple, PyPy a 6 différentes implémentations de récupération de place !

516

Vous pouvez utiliser pathlib .

Pour Python 3.5 et versions ultérieures:

from pathlib import Path
contents = Path(file_path).read_text()

Pour les versions inférieures de Python, utilisez pathlib2 :

$ pip install pathlib2

Ensuite:

from pathlib2 import Path
contents = Path(file_path).read_text()

Il s’agit de la mise en oeuvre de read_text :

def read_text(self, encoding=None, errors=None):
    """
    Open the file in text mode, read it, and close the file.
    """
    with self.open(mode='r', encoding=encoding, errors=errors) as f:
        return f.read()
73
Eyal Levin