Comment ajouter ou modifier l’encodage d’un fichier déjà ouvert en Python

Cet article vous enseigne ce que vous devez coder si vous souhaitez ajouter ou modifier l’encodage Unicode d’un fichier déjà ouvert – sans le fermer au préalable.

Si vous voulez ajouter l’encodage/décodage Unicode à un objet fichier déjà existant qui est ouvert en mode binaire, il suffit de l’envelopper avec un objet io.TextIOWrapper(). Par exemple:

import urllib.request
import io

purl = urllib.request.urlopen('https://www.programmation360.com')
f = io.TextIOWrapper(purl,encoding='utf-8')
texte = f.read()

Si vous voulez changer l’encodage d’un fichier texte déjà ouvert, utilisez sa méthode detach() pour supprimer le niveau d’encodage de texte existant avant de le remplacer par un nouveau. Voici un exemple de modification de l’encodage sur sys.stdout:

>>> import sys
>>> sys.stdout.encoding
'UTF-8'
>>> sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding='latin-1')
>>> sys.stdout.encoding
'latin-1'
>>>

Cela pourrait casser la sortie de votre terminal. C’est juste pour illustrer.

Le système d’E/S d’un système d’exploitation est constitué d’une série de couches. Vous pouvez voir ces couches vous-même en essayant cet exemple simple impliquant un fichier texte:

>>> f = open('exemple.txt','w')
>>> f
<_io.TextIOWrapper name='exemple.txt' mode='w' encoding='UTF-8'>
>>> f.buffer
<_io.BufferedWriter name='exemple.txt'>
>>> f.buffer.raw
<_io.FileIO name='exemple.txt' mode='wb'>
>>>

Dans cet exemple, io.TextIOWrapper est une couche de traitement de texte qui code et décode le texte d’un fichier en utilisant le codage Unicode.

io.BufferedWriter est une couche d’E/S tamponnée qui gère les données binaires, et io.FileIO est un fichier brut représentant le descripteur de fichier de bas niveau dans le système d’exploitation.

L’ajout ou la modification de l’encodage du texte implique l’ajout ou la modification de la couche supérieure io.TextIOWrapper.

En règle générale, il n’est pas sûr de manipuler directement les différentes couches en accédant aux attributs affichés. Par exemple, voyez ce qui se passe si vous essayez de modifier l’encodage en utilisant cette technique:

>>> f
<_io.TextIOWrapper name='exemple.txt' mode='w' encoding='UTF-8'>
>>> f = io.TextIOWrapper(f.buffer, encoding='latin-1')
>>> f
<_io.TextIOWrapper name='exemple.txt' encoding='latin-1'>
>>> f.write('Hello')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file.
>>>

Cela ne fonctionne pas parce que la valeur originale de f a été détruite et a fermé le fichier sous-jacent dans le processus.

La méthode detach() déconnecte la couche supérieure d’un fichier et retourne la couche inférieure suivante. Par la suite, la couche supérieure ne sera plus utilisable. Par exemple:

>>> f = open('exemple.txt', 'w')
>>> f
<_io.TextIOWrapper name='exemple.txt' mode='w' encoding='UTF-8'>
>>> b = f.detach()
>>> b
<_io.BufferedWriter name='exemple.txt'>
>>> f.write('hello')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: underlying buffer has been detached
>>>

Une fois détaché, cependant, vous pouvez ajouter une nouvelle couche supérieure au résultat retourné. Par exemple:

>>> f = io.TextIOWrapper(b, encoding='latin-1')
>>> f
<_io.TextIOWrapper name='exemple.txt' encoding='latin-1'>
>>>

Bien que la modification de l’encodage ait été montrée, il est également possible d’utiliser cette technique pour modifier la gestion des lignes, la politique d’erreur et d’autres aspects de la gestion des fichiers. Par exemple:

>>> sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding='ascii',
...                               errors='xmlcharrefreplace')
>>> print('Sape\u00f1o')
Sape&#241;o
>>>

Remarquez comment le caractère non ASCII n a été remplacé par &#241 dans la sortie.

LAISSER UN COMMENTAIRE

Please enter your comment!
Please enter your name here