web-dev-qa-db-fra.com

Comment imprimer utf-8 sur console avec Python 3.4 (Windows 8)?

Je n'ai jamais complètement compris le codage et le décodage de l'unicode vers d'autres formats (utf-8, utf-16, ascii, etc.), mais j'ai atteint un mur à la fois déroutant et frustrant. Ce que j'essaie de faire est d’imprimer les symboles de la carte utf-8 (♠, ♥, ♦, ♣) d’un module Python sur une console Windows. La console que j'utilise est git bash et j'utilise console2 en tant qu'interface frontale. J'ai essayé/lu plusieurs approches ci-dessous et rien n'a fonctionné jusqu'à présent. Dites-moi si ce que je fais est possible et quelle est la bonne façon de le faire.

  • Assurez-vous que la console peut gérer les caractères utf-8 ..__ Ces deux tests me font croire que la console n'est pas le problème.

enter image description here

  • Essayez la même chose depuis le module python.
    Lorsque j'exécute le .py, voici le résultat.

    print(u'♠')
    UnicodeEncodeError: 'charmap' codec can't encode character '\u2660' in position 0: character maps to <undefined>
    
  • Essayez de coder . Cela me restitue le jeu unicode codé en utf-8, mais toujours pas de symbole de pique. 

    text = '♠'
    print(text.encode('utf-8'))
    b'\xe2\x99\xa0'
    

J'ai l'impression qu'il me manque une étape ou que je ne comprends pas tout le processus de codage/décodage. J'ai lu ceci , ceci et ceci . La dernière des pages suggère d'encapsuler sys.stdout dans le code mais this article indique que l'utilisation de stdout est inutile et pointe vers une autre page à l'aide du module codecs.

Je suis tellement confus! Je pense qu'il est difficile de trouver une documentation de qualité sur ce sujet et j'espère que quelqu'un pourra éclaircir cette question. Toute aide est toujours appréciée!

Austin

22
Austin A

Ce que j'essaie de faire est d’imprimer les symboles de la carte utf-8 (♠, ♥, ♦, ♣) d’un module python sur une console Windows

UTF-8 est un codage octet de caractères Unicode. ♥ ♦ ♣ sont des caractères Unicode qui peuvent être reproduits dans une variété d'encodages et UTF-8 en est un. En UTF, UTF-8 peut reproduire n'importe quel caractère Unicode. Mais il n'y a rien de spécifiquement "UTF-8" à propos de ces personnages.

Les autres encodages pouvant reproduire les caractères ♠ ♥ ♦ sont Windows page de code 850 et 437 , que votre console est susceptible d’utiliser sous une installation de Windows en Europe occidentale. Vous pouvez imprimer dans ces codages, mais vous n'utilisez pas UTF-8 pour le faire, et vous ne pourrez pas utiliser d'autres caractères Unicode disponibles dans UTF-8 mais en dehors de la portée de ces pages de code.

print(u'♠')
UnicodeEncodeError: 'charmap' codec can't encode character '\u2660'

En Python 3, ceci est identique au test print('♠') que vous avez effectué ci-dessus. Il existe donc une différence dans la façon dont vous appelez le script contenant cette print par rapport à votre py -3.4. Qu'est-ce que sys.stdout.encoding vous donne du script?

Pour que print fonctionne correctement, vous devez vous assurer que Python sélectionne le bon encodage. S'il ne le fait pas correctement à partir des paramètres du terminal, vous devrez en effet définir PYTHONIOENCODING sur cp437.

>>> text = '♠'
>>> print(text.encode('utf-8'))
b'\xe2\x99\xa0'

print ne peut imprimer que des chaînes Unicode. Pour les autres types, y compris la chaîne bytes qui résulte de la méthode encode(), la représentation littérale (repr) de l'objet est obtenue. b'\xe2\x99\xa0' est le moyen d'écrire un littéral Python de 3 octets contenant un ♠ codé en UTF-8.

Si vous voulez ignorer le codage implicite de print dans PYTHONIOENCODING et le remplacer par le vôtre, vous pouvez le faire explicitement:

>>> import sys
>>> sys.stdout.buffer.write('♠'.encode('cp437'))

Ceci produira bien sûr une sortie incorrecte pour toutes les consoles ne tournant pas la page de code 437 (par exemple, les installations non européennes). En règle générale, pour les applications utilisant la stradio C, comme Python, obtenir des caractères non-ASCII sur la console Windows est trop peu fiable pour être gêné.

13
bobince

Ne pas encoder en utf-8; Imprimez directement Unicode à la place:

print(u'♠')

Voir comment imprimer Unicode sur une console Windows .

2
jfs

Par défaut, la console sous Microsoft Windows n'affiche que 256 caractères (cp437, de " page de code 437 ", le jeu de caractères IBM-PC 1981 étendu ASCII d'origine) comme vous le dites dans les commentaires.

et de l'autre côté, PYTHONIOENCODING est défini sur UTF-8 par défaut. Je pense donc que lorsque vous voulez imprimer unicode dans Windows, vous devez aligner sys.stdout.encoding et PYTHONIOENCODING avec ensemble! 

notez également que lorsque vous spécifiez un codage pour votre fichier.py, utilisez-le simplement pour ce code et ne modifiez pas le système par défautencoding

alors fais quelque chose comme ça: 

import codecs
my_str='♠' # or something like my_str='\u05dd' 
my_str.encode().decode('cp437')
0
Kasrâmvd