2010-03-23 13 views
2

Dans le pickle module documentation il y a un extrait de l'exemple de code:durée de python d'un objet de fichier dans une liste d'arguments

reader = pickle.load(open('save.p', 'rb')) 

qui lors de la première lecture semblait allouera un descripteur de fichier système, lire son contenu, puis "fuite" le descripteur ouvert car il n'y a pas de poignée accessible pour appeler close(). Cela m'a fait me demander s'il y avait une magie cachée qui s'occupe de cette affaire.

En plongeant dans la source, j'ai trouvé dans Modules/_fileio.c que les descripteurs de fichiers sont fermés par le destructeur fileio_dealloc() qui a conduit à la vraie question.

Quelle est la durée de l'objet fichier utilisé par l'exemple de code ci-dessus? Après que cette instruction s'exécute, l'objet devient-il effectivement non référencé et, par conséquent, le fd sera-t-il sujet à un appel close(2) réel lors d'un balayage futur de la récupération de place? Si oui, est-ce que la ligne d'exemple est une bonne pratique, ou ne devrait-on pas compter sur le fait que le fd soit libéré, risquant ainsi l'épuisement de la table de descripteurs par processus du noyau?

Répondre

3

Quelle est la durée de l'objet fichier retourné par l'exemple de code ci-dessus?

Ce code ne retour l'objet de fichier (comme le dit correctement, il reçoit comme argument le titre de Q).

Dans CPython actuel, le fichier sera fermé au moment où la fonction renvoie (puisque la fonction ne stocke aucune référence à l'objet fichier vers des emplacements plus durables). Dans d'autres implémentations, le fichier sera fermé "éventuellement" mais il n'y a pas d'heure précise spécifiée. Selon la sémantique de fermeture immédiate de CPython (qui peut changer quand un futur CPython se déplace vers de meilleurs mécanismes de collecte des ordures), alors qu'une approche très traditionnelle n'est pas la meilleure pratique.

plutôt meilleure pratique consiste à utiliser l'instruction with:

with open(...) as f: 
    reader = pickle.load(f) 

Avec cette utilisation, fermeture immédiate du fichier (dès que le corps de la déclaration with se termine) est garanti dans toutes les implémentations. Notez que dans Python 2.5, vous avez besoin d'un from __future__ import with_statement pour utiliser with. Dans 2.6 ou mieux, une telle "importation du futur" n'est pas nécessaire à cette fin (c'est inoffensif, mais si vous savez que vous ne serez jamais en cours d'exécution en vertu de 2.5 c'est redondant et mieux enlevé).

+0

merci beaucoup; vous aviez raison, je voulais dire "utilisé" plutôt que "retourné" et édité pour réparer. – msw