2009-05-09 6 views
4

J'ai un objet qui contient des données unicode et je veux l'utiliser dans sa représentation par exemple.comment utiliser la liste des objets python dont la représentation est unicode

# -*- coding: utf-8 -*- 

class A(object): 

    def __unicode__(self): 
     return u"©au" 

    def __repr__(self): 
     return unicode(self).encode("utf-8") 

    __str__ = __repr__ 

a = A() 


s1 = u"%s"%a # works 
#s2 = u"%s"%[a] # gives unicode decode error 
#s3 = u"%s"%unicode([a]) # gives unicode decode error 

Maintenant, même si je reviens unicode de rééd il donne toujours l'erreur si la question est de savoir comment puis-je utiliser une liste de ces objets et créer une autre chaîne unicode hors de lui?

détails de la plate-forme:

""" 
Python 2.5.2 (r252:60911, Jul 31 2008, 17:28:52) 
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2 
'Linux-2.6.24-19-generic-i686-with-debian-lenny-sid' 
""" 

aussi ne sais pas pourquoi

print a # works 
print unicode(a) # works 
print [a] # works 
print unicode([a]) # doesn't works 

répond groupe python qui http://groups.google.com/group/comp.lang.python/browse_thread/thread/bd7ced9e4017d8de/2e0b07c761604137?lnk=gst&q=unicode#2e0b07c761604137

Répondre

4

s1 = u"%s"%a # works

Cela fonctionne, parce que quand traitant 'a' il utilise sa représentation unicode (c.-à-d. la méthode unicode),

p dans une liste comme '[a]' ...Lorsque vous essayez de mettre cette liste dans la chaîne, ce qui s'appelle est l'unicode ([a]) (qui est le même que repr dans le cas d'une liste), la représentation sous forme de chaîne de la liste, qui utilisera 'repr (a) 'représenter votre article dans sa sortie. Cela causera un problème puisque vous passez un objet 'str' (une chaîne d'octets) qui contient la version encodée en utf-8 de 'a', et quand le format de chaîne essaye d'incorporer cela dans votre chaîne unicode, il essayez de le reconvertir en un objet Unicode en utilisant le codage par défaut hte, c'est-à-dire ASCII. car ascii n'a pas le caractère qu'il essaie de convertir, il échoue

ce que vous voulez faire devrait être fait de cette façon: u"%s" % repr([a]).decode('utf-8') en supposant que tous vos éléments encodent en utf-8 (ou ascii, qui est un utf -8 sous-ensemble du point de vue unicode).

pour une meilleure solution (si vous voulez toujours garder la chaîne à la recherche comme une liste str) vous devez utiliser ce qui a été suggéré précédemment, et utiliser rejoindre, en quelque chose comme ceci:

u '[%s]' % u','.join(unicode(x) for x in [a,a])

bien que cela ne s'occupe pas de la liste contenant la liste de vos objets A. Mon explication semble terriblement floue, mais j'espère que vous pouvez avoir un sens à partir de là.

0
# -*- coding: utf-8 -*- 

class A(object): 
    def __unicode__(self): 
     return u"©au" 

    def __repr__(self): 
     return unicode(self).encode('ascii', 'replace') 

    __str__ = __repr__ 

a = A() 

>>> u"%s" % a 
u'\xa9au' 
>>> u"%s" % [a] 
u'[?au]' 
+0

Pourquoi ?? downvote – Unknown

+0

cela n'a rien à voir avec remplacer car cet encodage fonctionne parfaitement, sinon erreur serait lors de l'encodage qui n'est pas –

+0

Pas besoin de gaspiller votre rep sur downvoting. Quand quelqu'un donne ce que vous croyez être la bonne réponse, il finira au sommet. – Shabbyrobe

0

rééd et str sont tous les deux supposés renvoyer des objets str, au moins jusqu'à Python 2.6.x. Vous obtenez l'erreur de décodage parce que repr() essaie de convertir votre résultat en str, et cela échoue.

Je crois que cela a changé dans Python 3.x.

+0

Je retourne l'objet str de repr sur cet objet fonctionne bien –

+0

Ah, désolé, vous avez raison. J'ai mal lu votre extrait de code. –

3

Essayez:

s2 = u"%s"%[unicode(a)] 

Votre principal problème est que vous faites plus de conversions que vous attendez. Permet de considérer les points suivants:

s2 = u"%s"%[a] # gives unicode decode error 

De Python Documentation,

 
    's'  String (converts any python object using str()). 
    If the object or format provided is a unicode string, 
    the resulting string will also be unicode. 

Quand est en cours de traitement de chaîne de format%, str ([a]) est appliquée. Ce que vous avez à ce stade est un objet chaîne contenant une séquence d'octets unicode. Si vous essayez d'imprimer ceci, il n'y a pas de problème, car les octets passent directement à votre terminal et sont restitués par le terminal.

>>> x = "%s" % [a] 
>>> print x 
[©au] 

Le problème survient lorsque vous tentez de le convertir en unicode. Essentiellement, la fonction unicode est appelée sur la chaîne qui contient la séquence d'octets codés en Unicode, et c'est ce qui provoque l'échec du codec ASCII.

 
    >>> u"%s" % x 
    Traceback (most recent call last): 
     File "", line 1, in 
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 1: ordinal not in range(128) 
    >>> unicode(x) 
    Traceback (most recent call last): 
     File "", line 1, in 
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 1: ordinal not in range(128) 
+0

donc la question reste comment j'utilise une telle liste d'objets pour créer une chaîne unicode y at-il un moyen facile? –

1

Si vous souhaitez utiliser une liste de unicode() objets capables de créer une chaîne de caractères unicode, essayer quelque chose comme:

u''.join([unicode(v) for v in [a,a]]) 
2

Tout d'abord, demandez-vous ce que vous essayez d'accomplir. Si tout ce que vous voulez est une représentation ronde déclenchable de la liste, il vous suffit de procéder comme suit:

class A(object): 
    def __unicode__(self): 
     return u"©au" 
    def __repr__(self): 
     return repr(unicode(self)) 
    __str__ = __repr__ 

>>> A() 
u'\xa9au' 
>>> [A()] 
[u'\xa9au'] 
>>> u"%s" % [A()] 
u"[u'\\xa9au']" 
>>> "%s" % [A()] 
"[u'\\xa9au']" 
>>> print u"%s" % [A()] 
[u'\xa9au'] 

Voilà comment il est censé fonctionner. La représentation sous forme de chaîne de listes python n'est pas quelque chose qu'un utilisateur devrait voir, il est donc logique d'y avoir des caractères échappés.

1

Puisque cette question implique beaucoup de choses unicode déroutantes, j'ai pensé que j'offrirais une analyse de ce qui se passait ici.

Tout se résume à l'implémentation des classes __unicode__ et __repr__ de la classe list. En gros, il est équivalent à:

class list(object): 
    def __repr__(self): 
     return "[%s]" % ", ".join(repr(e) for e in self.elements) 
    def __str__(self): 
     return repr(self) 
    def __unicode__(self): 
     return str(self).decode() 

En fait, list doesn't even define the __unicode__ and __str__ methods, ce qui est logique quand on y pense.

Lorsque vous écrivez:

u"%s" % [a]       # it expands to 
u"%s" % unicode([a])     # which expands to 
u"%s" % repr([a]).decode()   # which expands to 
u"%s" % ("[%s]" % repr(a)).decode() # (simplified a little bit) 
u"%s" % ("[%s]" % unicode(a).encode('utf-8')).decode() 

Cette dernière ligne est une extension de rééd (a), en utilisant la mise en œuvre de __repr__ dans la question. Comme vous pouvez le voir, l'objet est d'abord encodé dans utf-8, pour ensuite être décodé plus tard avec le codage par défaut du système, qui ne supporte généralement pas tous les caractères.

Comme certains des autres réponses mentionnées, vous pouvez écrire votre propre fonction, ou même sous-classe liste, comme suit:

class mylist(list): 
    def __unicode__(self): 
     return u"[%s]" % u", ".join(map(unicode, self)) 

Notez que ce format n'est pas rond-déclenchable. Il peut même être trompeur:

>>> unicode(mylist([])) 
u'[]' 
>>> unicode(mylist([''])) 
u'[]' 

Evidement, vous pouvez écrire une fonction quote_unicode pour le rendre rond-déclenchable, mais le moment est venu de demander youself what's the point.Les fonctions unicode et str sont destinées à créer une représentation d'un objet qui a du sens pour un utilisateur. Pour les programmeurs, il y a la fonction repr. Les listes brutes ne sont pas quelque chose qu'un utilisateur est supposé voir. C'est pourquoi la classe list n'implémente pas la méthode __unicode__.

Pour obtenir un peu meilleure idée de ce qui se passe quand, jouez avec cette petite classe:

class B(object): 
    def __unicode__(self): 
     return u"unicode" 
    def __repr__(self): 
     return "repr" 
    def __str__(self): 
     return "str" 


>>> b 
repr 
>>> [b] 
[repr] 
>>> unicode(b) 
u'unicode' 
>>> unicode([b]) 
u'[repr]' 

>>> print b 
str 
>>> print [b] 
[repr] 
>>> print unicode(b) 
unicode 
>>> print unicode([b]) 
[repr] 
Questions connexes