print : comment avoir une conversion d'encodage non bloquante ?
2 réponses
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 ?
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
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.
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') )
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.
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
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
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