Comment imprimer utf-8 à la console avec Python 3.4 (Windows 8)?
Je n'ai jamais entièrement enveloppé ma tête autour de codage et de décodage de l'unicode pour les autres formats (utf-8, utf-16, ascii, etc.) mais j'ai atteint un mur qui est à la fois déroutant et frustrant. Ce que j'essaie de faire est d'imprimer utf-8 symboles de carte (♠,♥,♦,♣) à partir d'un module python pour une console windows. La console que j'utilise est git bash et je suis en utilisant console2 comme un front-end. J'ai essayé de lire un certain nombre d'approches ci-dessous et rien n'a fonctionné jusqu'à présent. Laissez-moi savoir si ce que je fais est possible et la bonne façon de le faire.
- Veillé à ce que la console peut gérer les caractères utf-8.
Ces deux tests de me faire croire que la console n'est pas le problème.
-
Tenter la même chose à partir du module python.
Lorsque j'exécute le .py, c'est le résultat.print(u'♠') UnicodeEncodeError: 'charmap' codec can't encode character '\u2660' in position 0: character maps to <undefined>
-
Tentative de coder ♠.
Cela me redonne de l'unicode jeu codé en utf-8, mais toujours pas de bêche symbole.text = '♠' print(text.encode('utf-8')) b'\xe2\x99\xa0'
Je crois que je suis un raté une étape ou ne pas comprendre l'ensemble du procédé de codage/décodage. J'ai lu cette, cette, et cette. Le dernier des pages suggère d'emballage le sys.stdout dans le code mais cette article dit à l'aide de stdout est inutile et pointe vers une autre page en utilisant les codecs module.
Je suis tellement confus! J'ai l'impression que la pensée de la qualité de la documentation sur ce sujet est difficile à trouver et j'espère que quelqu'un peut éclaircir ce point. Toute aide est toujours appréciée!
Austin
- Comment utilisez-vous la .py? Avez-vous essayé le réglage de la
PYTHONIOENCODING
variable d'environnement? - wiki.python.org/moin/PrintFails
- juste ajouter
#encoding: utf-8
au-dessus de votre.py
- Cette question couvre un certain nombre de solutions possibles: stackoverflow.com/questions/4374455/...
- Merci à tous. @nneonneo, je suis de l'exécution de ma .py est à partir de la console. Je lance le py puis d'ouvrir un shell interactif à l'aide de cette ligne 'py -3.4 -je myfile.py'. Je tiens également à éviter de faire de grosses modifications comme la manipulation de la "PYTHONIOENCODING'. Mais plus je lis, plus je me rends compte que mon problème réside dans le codage par défaut de la console windows (cp437).
- S, j'ai certainement venir à travers cet article un certain nombre de fois, mais je suis encore à essayer de donner un sens à tout cela. Il est possible que la réponse se trouve à l'intérieur.
- la façon dont je le comprends python est source d'encodage est qu'il raconte l'OS d'exécuter le fichier encodage que le fichier doit avoir. Ce qui me confond ici, c'est cela. Un espace interactif de python session, lorsque je lance
print(sys.stdout.encoding)
il sorties cp437, ce qui est logique puisque c'est l'encodage par défaut de windows. Cependant, si je vous ajoute la suggestion (ou de toute autre source de codage) et de la place que la même ligne dans la .py, il encore sorties cp437. Je ne sais pas si c'est normal ou si il est possible que git bash/windows ne reconnaît pas ma source d'encodage.
Vous devez vous connecter pour publier un commentaire.
UTF-8 est un codage octet de caractères Unicode. ♠♥♦♣ sont des caractères Unicode qui peut être reproduit dans une variété de codages et de l'UTF-8 est l'un de ces codages—en tant que UTF, UTF-8 peut reproduire tout caractère Unicode. Mais il n'y a rien de spécifiquement “UTF-8” à propos de ces personnages.
D'autres codages qui peuvent reproduire les caractères ♠♥♦♣ sont Windows page de code 850 et Quatre cent trente sept, que votre console est susceptible d'utiliser en vertu d'une europe Occidentale installation de Windows. Vous pouvez imprimer ♠ dans ces encodages, mais vous n'êtes pas l'utilisation de l'UTF-8 pour ce faire, et vous ne serez pas en mesure d'utiliser d'autres caractères Unicode sont disponibles en UTF-8, mais en dehors de la portée de ces pages de code.
En Python 3 c'est le même que le
print('♠')
test que vous avez fait ci-dessus, si il ya quelque chose de différent à propos de la façon dont vous exécutez le script contenant ceprint
, par rapport à votrepy -3.4
. Ce n'sys.stdout.encoding
vous donner le script?Pour obtenir
print
travail correctement, vous devez veiller à Python prend le bon encodage. Si ce n'est pas adéquate à partir de la configuration du terminal vous aurait effectivement pour définirPYTHONIOENCODING
àcp437
.print
pouvez uniquement imprimer des chaînes Unicode. Pour les autres types, y compris lesbytes
chaîne de résultats de laencode()
méthode, il obtient la représentation littérale (repr
) de l'objet.b'\xe2\x99\xa0'
est la façon dont vous écrivez un Python de 3 octets contenant un littéral codé en UTF-8 ♠.Si ce que vous voulez faire est de contournement
print
s'implicite de l'encodage PYTHONIOENCODING et le remplacer par votre propre, vous pouvez le faire de manière explicite:Ce sera bien sûr de générer de fausses sortie pour toutes les consoles de ne pas l'exécution de code page 437 (par ex. non-Ouest-Européen installe). Généralement, pour les applications à l'aide de la C stdio, comme le Python, l'obtention des caractères non-ASCII pour la console Windows est tout simplement trop peu fiable pour s'embêter avec.
Ne pas encoder en utf-8; print Unicode directement à la place:
Voir comment imprimer Unicode pour console Windows.
from __future__ import unicode_literals
est utilisé.UnicodeEncodeError
peut être résolu en installantwin-unicode-console
package de ne pas utiliser l'utf-8 n'importe où (il fonctionne avec des chaînes Unicode directement). Suivez le lien dans la réponse.print('\xe7')
et poster comme un nouveau Débordement de Pile question avec le plein de sperme.Par défaut, la console de Microsoft Windows s'affiche uniquement 256 caractères (cp437, de "Page de Code 437", l'origine de l'IBM-PC 1981 jeu de caractères ASCII étendu) comme vous le dites dans les commentaires.
et de l'autre côté de la
PYTHONIOENCODING
est fixé àUTF-8
par défaut. je pense donc que lorsque vous souhaitez imprimer unicode dans windows, vous devez alignersys.stdout.encoding
etPYTHONIOENCODING
ensemble !notez également que lorsque vous spécifiez un encodage pour votre
.py
fichier, il suffit d'utiliser pour ce code et ne pas modifier la valeur par défaut du systèmeencoding
.donc faire quelque chose comme ceci :
Vous pouvez regarder cela de cette façon. Une chaîne est une séquence de caractères, pas une séquence d'octets. Les caractères Unicode codepoints. Les octets sont seulement des nombres dans la gamme de 0 à 255. Au niveau bas, les ordinateurs de travailler seulement avec les séquences d'octets. Si vous souhaitez imprimer une chaîne, vous appelez simplement
print(a_string)
en Python. Mais pour communiquer avec l'environnement de système d'exploitation, la chaîne doit être encodé à une séquence d'octets. Ceci est fait automatiquement quelque part sous le capot deprint
fonction. Le codage utilisé estsys.stdout.encoding
. Si vous obtenez uneUnicodeEncodeError
, cela signifie que vos personnages ne peuvent pas être codées en utilisant le codage en cours.Autant que je sache, il n'est actuellement pas possible d'exécuter du Python sur Windows, de façon que le codage utilisé est capables de coder tous les caractères (UTF-8 ou UTF-16) et à la fois assumée par Python et très utilisés par le système d'exploitation environnement d'entrée et de sortie. Il y a une solution: vous pouvez utiliser
win_unicode_console
paquet, qui vise à résoudre ce problème. Il suffit de l'installer parpip install win_unicode_console
, et dans votresitecustomize
à l'importation et à appelerwin_unicode_console.enable()
. Cela servira comme un externe patch pour votre installation de Python ragarding cette question. Voir la documentation pour plus d'informations: https://github.com/Drekin/win-unicode-console.win_unicode_console
démontre que vous pouvez écrire n'importe quel caractère Unicode (si seulement BMP caractères sera affiché par la console Windows).WriteConsoleW()
(utilisé parwin_unicode_console
) est un contre-exempleWriteConsoleW
comme l'acceptation d'un UTF-16-LE codées octets, pas une chaîne de caractères.unicode
type en Python 2 et sa mise en œuvre UCS-2, UCS-4 (étroit, large builds). La mise en œuvre peut être à améliorer.g,. Python 3 utilise la chaîne souple représentation mais l'abstraction reste le même. En particulier,WriteConsoleW()
peut avoir commencé comme UCS-2, mais c'est de l'utf-16le maintenant. Console Windows lui-même est encore UCS-2 c'est à dire, vous pouvez écrire (et le copier/coller) utf-16le, mais seulement BMP caractères peuvent être affichés (même la prise en charge des polices correspondantes astral caractères)unicode
type en Python 2, tandis que lors de la communication avec l'environnement de système d'exploitation, vous ne pouvez pas utiliser cette abstraction directement, vous devez coder en quelque sorte. Bien sûr, la mise en œuvre de launicode
utilise également venir codage interne.os.listdir(unicode_string)
fonctionne sur Unix (système d'exploitation utilise octets interfaces) et sur Windows (API Unicode). L'une des améliorations de Python 3, c'est qu'il utilise Unicode API plus sur Windows.print
ouos.listdir
. En fait, je voulais dire le contraire. Comme je l'ai dit “le codage est fait sous le capot”, “vous devez simplement appelerprint(a_string)
”, ce qui est exactement ce que vous suggérez.1.5
. Nous pouvons stocker dans la mémoire et sur le disque à l'aide de format binary32:b'\x00\x00\xc0\x3f'
. Si l'on applique votre logique il n'y a pas numérique interfaces il y a seulement octets interfaces. Les entiers sont codés comme des octets trop. Considérez-vouspid_t getpid()
être octets de l'interface? Octet est lui-même une abstraction si elle est tellement réussie et commun qui est impossible à distinguer de la réalité pour certaines personnes.