簡體   English   中英

__str __()是否在幕后調用encode()方法?

[英]Does __str__() call decode() method behind scenes?

在我看來,內置函數__repr____str__在基本定義上有重要區別。

>>> t2 = u'\u0131\u015f\u0131k'
>>> print t2
ışık
>>> t2
Out[0]: u'\u0131\u015f\u0131k'

由於t2是unicode字符串,因此t2.decode引發錯誤。

>>> enc = 'utf-8'
>>> t2.decode(enc)
------------------------------------------------------------
Traceback (most recent call last):
  File "<ipython console>", line 1, in <module>
  File "C:\java\python\Python25\Lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordin
al not in range(128)

__str__引發錯誤,就像正在調用__str__ decode()函數一樣:

>>> t2.__str__()
------------------------------------------------------------
Traceback (most recent call last):
  File "<ipython console>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordin
al not in range(128)

但是__repr__可以正常工作:

>>> t2.__repr__()
Out[0]: "u'\\u0131\\u015f\\u0131k'"

為什么__str__產生錯誤而__repr__正常工作?

這種小的差異似乎在我正在處理的一個Django應用程序中引起了錯誤。

基本上, __str__只能輸出ascii字符串。 由於t2包含高於ascii的unicode代碼點,因此不能僅用字符串來表示。 另一方面, __repr__嘗試輸出重新創建對象所需的python代碼。 您將看到repr(t2)的輸出(此語法優於t2.__repr_() )是您在第一行將t2設置為up的結果。 repr的結果大致類似於['\\','u','0',...],它們都是ascii值,但是str的輸出試圖是[chr(0x0131),chr(0x015f) ,chr(0x0131),'k'],其中大多數都超出python字符串可接受的字符范圍。 通常,在處理django應用程序時,應使用__unicode__進行所有操作,切勿觸摸__str__

django文檔中有關字符串的更多信息。

通常,調用str.__unicode__()unicode.__str__()是一個非常糟糕的主意,因為不能將字節安全地轉換為Unicode字符點,反之亦然。 ASCII值是一個例外,在所有單字節編碼中通常都相同。 問題是您使用了錯誤的轉換方法。

要將unicode轉換為str ,應使用encode()

>>> t1 = u"\u0131\u015f\u0131k"
>>> t1.encode("utf-8")
'\xc4\xb1\xc5\x9f\xc4\xb1k'

要將str轉換為unicode ,請使用decode()

>>> t2 = '\xc4\xb1\xc5\x9f\xc4\xb1k'
>>> t2.decode("utf-8")
u'\u0131\u015f\u0131k'

為John的好答案提供一些支持:

為了理解這兩種方法的命名encode()decode() ,您只需要看Python認為u'...'形式的unicode字符串就是參考格式 您將參考格式編碼為另一種格式(例如utf-8),然后從其他格式解碼以得到參考格式。 Unicode格式始終被認為是“真實的東西” :-)。

請注意,在Python 3中,unicode是默認設置,而__str__()應該始終為您提供unicode。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM