You are here: Sommaire > Plongez au coeur de Python > Traitement des exceptions et utilisation de fichiers > Les objets-fichier | << >> | ||||
Plongez au coeur de PythonDe débutant à expert |
Python a une fonction prédéfinie, open, pour ouvrir un fichier sur le disque. open retourne un objet-fichier qui possède des méthodes et des attributs pour obtenir des informations et manipuler le fichier ouvert.
>>> f = open("/music/_singles/kairo.mp3", "rb") >>> f <open file '/music/_singles/kairo.mp3', mode 'rb' at 010E3988> >>> f.mode 'rb' >>> f.name '/music/_singles/kairo.mp3'
La méthode open peut prendre jusqu'à trois paramètres : un nom de fichier, un mode et un paramètre de tampon. Seul le premier, le nom de fichier, est nécéssaire, les deux autres sont optionnels. Si le mode n'est pas spécifié, le fichier est ouvert en mode texte pour la lecture. Ici nous ouvrons le fichier en mode binaire pour la lecture (print open.__doc__ affiche une bonne explication de tous les modes possibles). | |
La fonction open retourne un objet (arrivé à ce point cela ne doit pas vous surprendre). Un objet-fichier à plusieurs attributs utiles. | |
L'attribut mode d'un objet-fichier vous indique dans quel mode le fichier a été ouvert. | |
L'attribut name d'un objet-fichier vous indique le nom du fichier qui a été ouvert. |
Une fois un fichier ouvert, la première chose que l'on peut faire est de le lire, comme nous allons le voir dans l'exemple suivant.
>>> f <open file '/music/_singles/kairo.mp3', mode 'rb' at 010E3988> >>> f.tell() 0 >>> f.seek(-128, 2) >>> f.tell() 7542909 >>> tagData = f.read(128) >>> tagData 'TAGKAIRO****THE BEST GOA ***DJ MARY-JANE*** Rave Mix 2000http://mp3.com/DJMARYJANE \037' >>> f.tell() 7543037
Les fichiers ouverts consomment des ressources système et, en fonction du mode d'ouverture, peuvent ne pas être accessibles à d'autres programmes. Il est donc important de fermer les fichiers dès que vous ne les utilisez plus.
>>> f <open file '/music/_singles/kairo.mp3', mode 'rb' at 010E3988> >>> f.closed False >>> f.close() >>> f <closed file '/music/_singles/kairo.mp3', mode 'rb' at 010E3988> >>> f.closed True >>> f.seek(0) Traceback (innermost last): File "<interactive input>", line 1, in ? ValueError: I/O operation on closed file >>> f.tell() Traceback (innermost last): File "<interactive input>", line 1, in ? ValueError: I/O operation on closed file >>> f.read() Traceback (innermost last): File "<interactive input>", line 1, in ? ValueError: I/O operation on closed file >>> f.close()
L'attribut closed d'un objet-fichier indique si l'objet pointe un fichier ouvert ou non. Dans ce cas, le fichier est toujours ouvert (closed vaut False). | |
Pour fermer un fichier, appelez la méthode close de l'objet-fichier. Cela libère le verrou (s'il existe) que vous avez sur le fichier, purge les tampons en écriture (s'ils existent) et libère les ressources système. | |
L'attribut closed confirme que le fichier est fermé. | |
Ce n'est pas parce que le fichier est fermé que l'objet fichier cesse d'exister. La variable f continuera d'exister jusqu'à ce qu'elle soit hors de portée ou qu'elle soit supprimée manuellement. Cependant aucune des méthodes de manipulation d'un fichier ouvert ne marchera après que le fichier ait été fermé, elles déclencheront toutes une exception. | |
Appeler close sur un objet-fichier dont le fichier est déjà fermé ne déclenche pas d'exception mais échoue silencieusement. |
Maintenant vous en avez vu assez pour comprendre le code de gestion de fichier dans le programme d'exemple fileinfo.py du chapitre précédent. L'exemple suivant montre comment ouvrir et lire un fichier de manière sûre en gérant les erreurs.
try: fsock = open(filename, "rb", 0) try: fsock.seek(-128, 2) tagdata = fsock.read(128) finally: fsock.close() . . . except IOError: pass
Comme l'ouverture et la lecture de fichiers est risquée et peut déclencher une exception, tout ce code est enveloppé dans un bloc try...except (alors, l'indentation standardisée n'est-elle pas admirable ? C'est là que l'on commence a vraiment l'apprécier). | |
La fonction open peut déclencher une exception IOError (peut-être que le fichier n'existe pas). | |
La méthode seek peut déclencher une exception IOError (peut-être que le fichier fait moins de 128 octets). | |
La méthode read peut déclencher une exception IOError (peut-être que le disque a un secteur défectueux ou le fichier est sur le réseau et le réseau est en rideau). | |
Voilà qui est nouveau : un bloc try...finally. Une fois le fichier ouvert avec succès par la fonction open, nous voulons être absolument sûrs que nous le refermons, même si une exception est déclenchée par les méthodes seek ou read. C'est à cela que sert un bloc try...finally : le code du bloc finally sera toujours exécuté, même si une exception est déclenchée dans le bloc try. Pensez-y comme à du code qui est exécuté «au retour», quoi qu'il se soit passé «en route». | |
Enfin, nous gérons notre exception IOError. Cela peut être l'exception IOError déclenchée par l'appel à open, seek, ou read. Ici, nous ne nous en soucions vraiment pas car tout ce que nous faisons et d'ignorer l'erreur et de continuer (rappelez-vous que pass est une instruction Python qui ne fait rien). C'est tout à fait légal, «gérer» une exception peut vouloir dire explicitement ne rien faire. Cela compte quand même comme une exception gérée et le traitement va reprendre normalement à la prochaine ligne de code après le bloc try...except. |
Nous pouvons bien sûr écrire dans un fichier, cela se fait en grande partie de la même manière que pour la lecture. Il y a deux modes d'ouverture de base :
Les deux modes créeront le fichier automatiquement s'il n'existe pas encore, il n'y a donc pas besoin de logique du type «si le fichier de journalisation n'existe pas, créer un nouveau fichier vide et l'ouvrir en écriture.» Il suffit d'ouvrir le fichier pour commencer à y écrire.
>>> logfile = open('test.log', 'w') >>> logfile.write('test succeeded') >>> logfile.close() >>> print file('test.log').read() test succeeded >>> logfile = open('test.log', 'a') >>> logfile.write('line 2') >>> logfile.close() >>> print file('test.log').read() test succeededline 2
<< Traitement des exceptions et utilisation de fichiers |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
Itérations avec des boucles for >> |