2010-10-20 5 views
25

Python newbie devient un peu frustré avec le module csv. À ce rythme, il aurait été plus simple d'écrire l'analyseur de fichier moi-même, mais je veux faire les choses de la manière Pythonienne ...CSVWriter n'enregistre pas les données dans le fichier - POURQUOI?

J'ai écrit un petit script python qui devrait enregistrer mes données dans un fichier CSV .

Voici un extrait de mon code:

import csv 

wrtr = csv.writer(open('myfile.csv','wb'),delimiter=',', quotechar='"') 

for row in rows: 
    wrtr.writerow([row.field1,row.field2,row.field3]) 

Le fichier myfile.csv est créé avec succès, mais il est vide - mais a un verrou sur elle, comme toujours utilisé par le processus Python. Il semble que les données ont été écrites dans le fichier en mémoire, mais elles n'ont pas encore été vidées sur le disque.

Étant donné que le processus Python maintient un verrou sur le fichier, je suppose que je suis responsable de la libération du verrou. Voici mes questions:

  1. Comment puis-je obtenir python pour vider le disque
  2. Comment puis-je fermer le fichier qui a été ouvert dans la méthode csv.writer()?
+29

"" "cela aurait été plus simple si j'avais écrit l'analyseur de fichier moi-même" "" - je le classerai sous "fameux derniers mots". –

+0

L'intuition principale est que le handle de fichier est toujours ouvert après que vous écrivez à l'auteur de csv. Si vous supprimez l'appel 'open' à l'extérieur et que vous maintenez un handle de fichier séparé que vous transmettez dans csv.writer (csvFile, ...), vous pouvez fermer ce handle de fichier lorsque vous avez terminé et que cela videra. La réponse fournie par Tim explique certains bons moyens de le faire. – mindthief

+0

csvwriter manque une méthode flush, c'est un oubli. –

Répondre

38

Utilisez

with open('myfile.csv','wb') as myfile: 
    wrtr = csv.writer(myfile, delimiter=',', quotechar='"') 
    for row in rows: 
     wrtr.writerow([row.field1,row.field2,row.field3]) 
     myfile.flush() # whenever you want 

ou

myfile = open('myfile.csv','wb') 
wrtr = csv.writer(myfile, delimiter=',', quotechar='"') 
for row in rows: 
    wrtr.writerow([row.field1,row.field2,row.field3]) 
    myfile.flush() # whenever you want, and/or 
myfile.close() # when you're done. 

La bonne chose au sujet de la première approche est que votre fichier sera également automatiquement fermé correctement en cas d'exception.

Si vous souhaitez que votre objet de fichier soit anonyme, il ne sera fermé que lorsque le programme sera fermé. Quand ou si elle est vidée dépend du système d'exploitation - donc ce ne sera peut-être jamais jusqu'à la sortie.

+0

Je ne ferais pas flush() 'dans chaque étape d'itération quand il n'est pas nécessaire de surveiller le fichier contenu au cours de l'itration 'pour row in rows'. –

+1

@ Jan-PhilipGehrcke: C'est pourquoi j'ai écrit "quand vous voulez" dans le commentaire après cette commande. –

+0

@Tim J'ai compris que vous vouliez dire ça. Je voulais juste que ce soit clair pour les autres :). –

5

Les méthodes flush() et close() du file object. Ou utilisez with.

+0

Mais je crée un objet fichier 'anonyme' - donc je n'ai rien à appeler flush et close contre. À moins de me tromper, cela signifie que je devrai modifier légèrement le code pour cliver un objet de fichier avant de le passer à la fonction csv.writer(). Je peux ensuite appeler flush() et close() sur l'objet fichier comme vous l'avez suggéré. Si tel est le cas, alors la documentation sur http://docs.python.org/library/csv.html est en effet aussi inutile/trompeuse que je le pense, et je ne ferai JAMAIS référence à nouveau. – skyeagle

+0

Fonctionne bien ici. Ce pourrait être quelque chose d'effrayant que Windows est en train de faire. –

+5

"Mais je crée un objet fichier 'anonyme'". Ne pas. –

Questions connexes