Question

Je regardais cette question et a commencé à se demander qu'est-ce que le fait print faire.

Je ne l'ai jamais trouvé comment utiliser string.decode() et string.encode() pour obtenir une chaîne unicode « out » dans le python shell interactif dans le même format que l'impression ne. Peu importe ce que je fais, je reçois soit

  1. UnicodeEncodeError ou
  2. la chaîne échappé à la notation "\ x ##" ...

Ceci est 2.x python, mais je suis déjà essayer de réparer mes voies et fait appel print():)

Exemple:

>>> import sys
>>> a = '\xAA\xBB\xCC'
>>> print(a)
ª»Ì
>>> a.encode(sys.stdout.encoding)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
UnicodeDecodeError: 'ascii' codec can't decode byte 0xaa in position 0: ordinal not in range(128)
>>> a.decode(sys.stdout.encoding)
u'\xaa\xbb\xcc'

EDIT :

Pourquoi suis-je pose cette question? Je suis malade et fatigué d'erreurs de encode() et réalisé que depuis print peut le faire (au moins dans le shell interactif). Je sais que le DOIT être un moyen pour faire comme par magie l'encodage CORRECTEMENT , en creusant l'info ce codage à utiliser de quelque part ...

INFO ADDITIONNELLE : Je suis en Python 2.4.3 (# 1, 3 septembre 2009, 15:37:12) [GCC 4.1.2 20.080.704 (Red Hat 4.1.2-46)] sur linux2

>>> sys.stdin.encoding
'ISO-8859-1'
>>> sys.stdout.encoding
'ISO-8859-1'

Cependant, les résultats sont les mêmes avec Python 2.6.2 (R262: 71600 8 Sep 2009, 13:06:43) sur la même case linux

.
Était-ce utile?

La solution

EDIT: (changements majeurs entre cette édition et le précédent ... Note:. J'utilise Python 2.6.4 sur une boîte Ubuntu)

Tout d'abord, dans ma première tentative de réponse, j'ai fourni quelques informations générales sur print et str que je vais laisser ci-dessous au bénéfice de toute personne ayant des problèmes plus simples avec print et chancing sur cette question. Quant à une nouvelle tentative de traiter la question vécue par l'OP ... En fait, je suis enclin à dire qu'il n'y a pas de solution miracle ici et si print réussit à donner un sens d'une chaîne bizarre littérale, alors ce n'est pas un comportement reproductible . Je suis conduit à cette conclusion par l'interaction drôle suivante avec Python dans ma fenêtre de terminal:

>>> print '\xaa\xbb\xcc'
��

Avez-vous essayé d'entrer ª »Ì directement à partir du terminal? A un terminal Linux utilisant utf-8 comme encodage, cela est réellement lu en tant que six octets, qui peuvent ensuite être faites pour ressembler à trois caractères unicode avec l'aide de la méthode decode:

>>> 'ª»Ì'
'\xc2\xaa\xc2\xbb\xc3\x8c'
>>> 'ª»Ì'.decode(sys.stdin.encoding)
u'\xaa\xbb\xcc'

Ainsi, le '\xaa\xbb\xcc' n'a de sens littéral si vous décodent comme latin-1 littéral (bien, vous pouvez réellement utiliser un codage différent qui est d'accord avec latin-1 sur les personnages concernés). En ce qui concerne print « juste travail » dans votre cas, certainement pas pour moi - comme mentionné ci-dessus

.

Ceci est expliqué par le fait que lorsque vous utilisez une chaîne de caractères non préfixé avec un u - à savoir "asdf" plutôt que u"asdf" - la chaîne résultante utilisera un codage non-unicode. Non; En fait, l'objet chaîne elle-même va être encodage pas au courant, et vous allez devoir le traiter comme si elle était codé avec le codage x, pour la valeur correcte de x. Cette idée de base me conduit à ce qui suit:

a = '\xAA\xBB\xCC'
a.decode('latin1')
# result: u'\xAA\xBB\xCC'
print(a.decode('latin1'))
# output: ª»Ì

Notez l'absence d'erreurs de décodage et la sortie correcte (que je pense à rester bon à tout autre boîte). Apparemment, votre chaîne littérale peut être le sens de par Python, mais pas sans aide.

Est-ce que cette aide? (Au moins pour comprendre comment les choses fonctionnent, sinon à faire le traitement des codages plus facile ...)


Maintenant, pour quelques morceaux drôles avec une valeur explicative (je l'espère)! Cela fonctionne bien pour moi:

sys.stdout.write("\xAA\xBB\xCC".decode('latin1').encode(sys.stdout.encoding))

Sauter soit le décodage ou de la partie codent pour résultat une exception liée unicode. En théorie, cela est logique, comme le premier décodage est nécessaire pour décider quels caractères il y a dans la chaîne donnée (la seule chose évidente à première vue est ce que octets il y a - l'idée Python 3 ayant (unicode) chaînes de caractères et octets pour, bien, octets, semble soudain superbement raisonnable), tandis que le codage est nécessaire pour que la sortie respecte l'encodage du flux de sortie. Maintenant, ce

sys.stdout.write("ąöî\n".decode(sys.stdin.encoding).encode(sys.stdout.encoding))

fonctionne comme prévu, mais les personnages viennent en fait à partir du clavier et sont donc en fait codé avec le codage stdin ... En outre,

ord('ą'.decode('utf-8').encode('latin2'))

renvoie le 177 correct (mon codage d'entrée est utf-8), mais \ XC4 \ x85'.encode ( 'latin2 « ) n'a pas de sens à Python, car il n'a pas la moindre idée de la façon de donner un sens » \ XC4 \ x85' et les chiffres qui en essayant le « code ascii » est le meilleur qu'il peut faire.


La réponse originale:

Le bit correspondant de docs Python (pour la version 2.6.4) dit que print(obj) est destiné à imprimer la chaîne donnée par str(obj). Je suppose que vous pouvez ensuite l'envelopper dans un appel à unicode (comme dans unicode(str(obj))) pour obtenir une chaîne unicode sur - ou vous pouvez simplement utiliser Python 3 et échanger cette nuisance particulière pour deux différents. ; -)

Par ailleurs, cela montre que vous pouvez manipuler le résultat de printing un objet comme vous pouvez manipufin le résultat de l'appel str sur un objet, qui est par déconner avec la méthode __str__. Exemple:

class Foo(object):
    def __str__(self):
        return "I'm a Foo!"

print Foo()

En ce qui concerne la mise en œuvre effective de print, je pense ce ne sera pas utile du tout, mais si vous vraiment veulent savoir ce qui se passe ... Il est dans le fichier Python/bltinmodule.c dans le Python sources (je suis à la recherche de la version 2.6.4). Rechercher une ligne commençant par builtin_print. Il est en fait tout à fait simple, pas de magie passe là-bas. : -)

Espérons que cela répond à votre question ... Mais si vous avez un problème plus Arcane que je me manque tout à fait, faire un commentaire, je vais faire une deuxième tentative. De plus, je suppose que nous avons affaire à Python 2.x; sinon je crois que je ne serais pas un commentaire utile.

Autres conseils

print() utilise sys.stdout.encoding pour déterminer ce que la console de sortie peut comprendre et utilise ensuite ce codage dans l'appel à str.encode().

[EDIT] Si vous regardez la source , il obtient sys.stdout puis appelle:

PyFile_WriteObject(PyTuple_GetItem(args, i), file,
                 Py_PRINT_RAW);

Je suppose que la magie est Py_PRINT_RAW mais la source juste dit:

    if (flags & Py_PRINT_RAW) {
    value = PyObject_Str(v);
    }

Donc pas de magie ici. Une boucle sur les arguments avec sys.stdout.write(str(item)) devrait faire l'affaire.

>>> import sys
>>> a = '\xAA\xBB\xCC'
>>> print(a)
ª»Ì

Tout print fait ici est en train d'écrire brut octets pour sys.stdout. La a chaîne est une chaîne d'octets, pas de caractères Unicode.

  

Pourquoi suis-je pose cette question? Je suis malade et fatigué des erreurs de encode () et réalisé que depuis l'impression peut le faire (au moins dans le shell interactif). Je sais que le MUST être un moyen de faire comme par magie l'encodage CORRECTEMENT, en creusant l'info ce codage à utiliser de quelque part ...

Hélas non, print ne fait rien du tout ici magique. Vous lui quelques octets, il vide les octets à stdout.

Pour utiliser .encode() et .decode() correctement, vous devez comprendre la différence entre les octets et les personnages, et je crains que vous ne devez trouver le bon codage à utiliser.

import sys

source_file_encoding = 'latin-1' # if there is no -*- coding: ... -*- line

a = '\xaa\xbb\xcc' # raw bytes that represent string in source_file_encoding

# print bytes, my terminal tries to interpret it as 'utf-8'
sys.stdout.write(a+'\n') 
# -> ��

ua = a.decode(source_file_encoding)
sys.stdout.write(ua.encode(sys.stdout.encoding)+'\n')
# -> ª»Ì

Définition Python code source codages

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top