Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

print : comment avoir une conversion d'encodage non bloquante ?

2 réponses
Avatar
PIGUET Bruno
Bonjour,

Lorsqu'on fait un print d'une chaîne unicode, python essaie de la
convertir automatiquement vers l'encodage de sys.stdout

C'est bien, c'est pratique, ça permet d'avoir un source codé en
latin-9 qui affiche les bons accents dans une console en utf-8, ou
réciproquement.

Mais y'a une chose qui ne me plaît pas : la fonction encode est
appelée en mode "strict". Ce qui fait que, si la chaîne comporte un
caractère non-représentable dans le codage de sortie, on a droit à une
belle exception (et, la plupart du temps, à la fin du programme).

Ce cas arrive lorsque stdout est redirigé vers un fichier.
sys.stdout.encoding() renvoie None, donc python essaie d'encoder en ascii
(probablement le résultat de sys.getdefaultencoding()), et ça bloque pour
tous les accents.

Actuellement, je m'en sort en appelant moi-même la fonction encode,
pour lui passer l'argument "replace". Ça marche, mais je ne bénéficie
plus de l'automatisme de print.

def mon_print(msg):
""" Écrit un message sur stdout, en faisant à peu près la même
conversion de formattage de caractères que print, mais avec une
option "replace", ce qui évite les erreurs bloquantes.
"""
if sys.stdout.isatty():
encoding = sys.getdefaultencoding()
else:
encoding = sys.stdout.encoding
sys.stdout.write ( (msg + '\n').encode(encoding, 'replace') )


Dans la doc de sys, j'ai cherche un sys.setencodingstrictness(), mais
je n'ai pas trouvé.

Quelqu'un connaît-il une méthode qui m'éviterait d'écrire une
fonction wrapper telle que celle-ci ?

Merci,

Bruno.

2 réponses

Avatar
PIGUET Bruno
Y'a une erreur de copier-coller.

La bonne version est :

def mon_print(msg):
""" Écrit un message sur stdout, en faisant à peu près la même
conversion de formattage de caractères que print, mais avec une
option "replace", ce qui évite les erreurs bloquantes.
"""
if sys.stdout.isatty():
encoding = sys.stdout.encoding
else:
encoding = sys.getdefaultencoding()
sys.stdout.write ( (msg + 'n').encode(encoding, 'replace') )

Bruno.
Avatar
News123
On 09/01/2010 09:50 AM, PIGUET Bruno wrote:
Bonjour,

Lorsqu'on fait un print d'une chaîne unicode, python essaie de la
convertir automatiquement vers l'encodage de sys.stdout

C'est bien, c'est pratique, ça permet d'avoir un source codé en
latin-9 qui affiche les bons accents dans une console en utf-8, ou
réciproquement.

Mais y'a une chose qui ne me plaît pas : la fonction encode est
appelée en mode "strict". Ce qui fait que, si la chaîne comporte un
caractère non-représentable dans le codage de sortie, on a droit à une
belle exception (et, la plupart du temps, à la fin du programme).

Ce cas arrive lorsque stdout est redirigé vers un fichier.
sys.stdout.encoding() renvoie None, donc python essaie d'encoder en ascii
(probablement le résultat de sys.getdefaultencoding()), et ça bloque pour
tous les accents.

Actuellement, je m'en sort en appelant moi-même la fonction encode,
pour lui passer l'argument "replace". Ça marche, mais je ne bénéficie
plus de l'automatisme de print.

def mon_print(msg):
""" Écrit un message sur stdout, en faisant à peu près la même
conversion de formattage de caractères que print, mais avec une
option "replace", ce qui évite les erreurs bloquantes.
"""
if sys.stdout.isatty():
encoding = sys.getdefaultencoding()
else:
encoding = sys.stdout.encoding
sys.stdout.write ( (msg + 'n').encode(encoding, 'replace') )


Dans la doc de sys, j'ai cherche un sys.setencodingstrictness(), mais
je n'ai pas trouvé.





Tu peux creer tom propre object, qui va remplacer sys.stdout
et qui utilise le filehandle de sys.stdout original.

Example non verifiee



class MyStdoutWithMyEncoding(object):
def __init__(self):
self.stdout_orig = sys.stdout

def write(self, data):

self.stdout_orig.write ( data.encode(encoding, 'replace') )


def flush(self):
self.stdout_orig.flush()


sys.stdout = MyStdoutWithMyEncoding()


print "whatever with illegal encoding"