2009-05-09 9 views
4

私はユニコードデータを含むオブジェクトを持っていて、その表現でそれを使用したいと思います。 表現がユニコードであるようなPythonオブジェクトのリストの使用方法

# -*- 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 

今、私はのreprからUnicodeを返す場合でも、それはまだその質問はどのように私は、このようなオブジェクトのリストを使用して、そこから別のUnicode文字列を作成することができますされ、エラー を与えますか?

プラットフォームの詳細:また

""" 
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' 
""" 

わからない理由

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

のpythonグループは答えること http://groups.google.com/group/comp.lang.python/browse_thread/thread/bd7ced9e4017d8de/2e0b07c761604137?lnk=gst&q=unicode#2e0b07c761604137

答えて

4

s1 = u"%s"%a # works

これは、作品を扱う際ため「」ユニコード表現(すなわち、ユニコードメソッド)、

を使用していますが、 '[a]'のようなリストの中に...そのリストを文字列に入れようとすると、unicode([a])(リストの場合はreprと同じです)、リストの文字列表現( 'repr a) 'あなたのアイテムをその出力で表現する。これはutf-8でエンコードされたバージョンの 'a'を含む 'str'オブジェクト(バイトの文字列)を渡しているため、文字列フォーマットがユニコード文字列に埋め込みしようとすると問題になります。それをhteのデフォルトのエンコーディング、すなわちASCIIを使ってユニコードオブジェクトに戻してみてください。 asciiには変換しようとしている文字はありませんので、それは失敗します。

このようにする必要があるのはu"%s" % repr([a]).decode('utf-8')です。あなたのすべての要素がutf-8(またはascii Unicodeの観点からはサブセット-8)。

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

:あなたはこのようなもので、参加する以前に示唆されたものを使用し、使用しなければならないでしょう(あなたはまだリストのstrのように見える文字列を維持したい場合)よりよい解決策のための

これはあなたのAオブジェクトのリストを含むリストの世話をしません。

私の説明はひどく不明瞭に聞こえますが、あなたはそれを理解することを願っています。

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

を?? – Unknown

+0

これはエンコードが完全に動作するため、これとは何の関係もありません。そうでなければエラーはエンコーディングされません。 –

+0

downvotingで担当者を浪費する必要はありません。あなたが正解と信じていることを誰かが与えると、それは一番上に終わるでしょう。 – Shabbyrobe

0

のreprSTRは、少なくともPython 2.6.xまで、strオブジェクトを返すことになっています。 repr()はあなたの結果をstrに変換しようとしているので、デコードエラーが発生しています。失敗しています。

これはPython 3.xで変更されていると思います。

+0

私はそのオブジェクト上のstrオブジェクトreprを返しています –

+0

ああ、申し訳ありません、あなたは正しいです。あなたのコードスニペットを誤解しました。 –

3

試してみてください。

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

あなたの主な問題は、あなたが期待する以上の変換を行っているということです。

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

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. 

を%sのフォーマット文字列が処理されている、STR([A])が印加された場合:以下の点を考慮することができます。この時点であなたが持っているのは、一連のユニコードバイトを含む文字列オブジェクトです。これを試して印刷しても問題はありません。なぜならバイトは端末にまっすぐに通って端末によってレンダリングされるからです。

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

問題は、ユニコードに変換しようとすると発生します。基本的に、関数unicodeは、Unicodeでエンコードされたバイトのシーケンスを含む文字列で呼び出されているため、asciiコーデックが失敗する原因となっています。あなたがunicode文字列を作成するためにunicode()できるオブジェクトのリストを使用したい場合は

 
    >>> 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

質問がユニコード文字列を作成するためにこのようなオブジェクトのリストを使用する方法は残っている 簡単な方法はありますか? –

1

、何かしてみてください:

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

まず、達成しようとしていることを尋ねてください。あなたが望むすべてがリストのラウンドtrippable表現がある場合は、単純に次の操作を行う必要があります。動作するようになっていますか

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'] 

がそれです。 Pythonのリストの文字列表現は、ユーザが見るべきものではないので、エスケープされた文字をそれらの中に持つのは理にかなっています。

1

この質問には多大な混乱を招くユニコードが含まれているので、私はここで何が起こっているのか分析したいと考えました。

listクラスの__unicode____repr__の実装になります。あなたはそれについて考えるとき、理にかなって実際

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() 

list doesn't even define the __unicode__ and __str__ methods、:基本的に、それは同等です。

あなたが書いた:

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() 

最後の行が問題の__repr__の実装を使用してのreprの拡大(a)は、されていること。

このように、オブジェクトは最初にutf-8でエンコードされます。後でシステムのデフォルトエンコードでデコードされます。これは通常はすべての文字をサポートしません。言及した他の回答の一部として

、あなたはそうのように、独自の機能、あるいはサブクラスのリストを記述することができます。この形式は、ラウンドtrippableではないことを

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

注意。それも、誤解を招くことができます:讲义1コースの

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

、あなたはそれがラウンドtrippable作るためにquote_unicode関数を書くことができますが、これはyouself what's the pointを依頼する瞬間です。unicodeおよびstr関数は、ユーザーにとって意味のあるオブジェクトの表現を作成するためのものです。プログラマーにとって、repr関数があります。生のリストは、ユーザーが今までに見ていたものではありません。そのため、listクラスは__unicode__メソッドを実装していません。

この小さなクラスで遊ぶとき、何が起こるかについて幾分良いアイデアを取得するには:なぜdownvote

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] 
関連する問題