2009-08-20 69 views
182

是否有一個Python約定,當你應該實現__str__()__unicode__()。我看到類比__str__()更頻繁地覆蓋__unicode__(),但它看起來並不一致。是否有更好的實施方法和其他方法的具體規則?是否有必要/好的做法來實現兩者?Python __str__與__unicode__

回答

227

__str__()是舊的方法 - 它返回字節。 __unicode__()是新的首選方法 - 它返回字符。這些名稱有點令人困惑,但在2.x中,出於兼容性原因,我們堅持使用它們。一般來說,你應該把所有的字符串格式化__unicode__(),並創建一個存根__str__()方法:

def __str__(self): 
    return unicode(self).encode('utf-8') 

在3.0,str包含的字符,所以同樣的方法被命名爲__bytes__()__str__()。這些行爲如預期。

+1

你是指創建__unicode__和__str__方法,或者只是保留_(u「」)中的字符串並創建__string__(不使用unicode方法)? – muntu 2010-09-03 12:59:39

+9

只有其中一個實施有沒有陷阱?當你只實現'__unicode__'然後執行'str(obj)'時會發生什麼? – RickyA 2013-02-06 09:09:31

+9

'unicode'在Python 3上引發了一個'NameError',是一個可以在2和3之間運行的簡單模式? – 2013-03-24 08:05:08

9

隨着世界越來越小,您遇到的任何字符串可能最終都會包含Unicode。所以對於任何新的應用程序,您至少應該提供__unicode__()。無論你是否也覆蓋__str__(),這只是一個口味問題。

19

如果我不特別關心給定類的微優化字符串化,我總是隻實現__unicode__,因爲它更通用。當我關心這種微小的性能問題(這是例外,而不是規則)時,只有__str__(當我可以證明字符串輸出中永遠不會有非ASCII字符)或兩者都有(當兩者都可能時),可能有幫助。

這些我認爲是可靠的原則,但在實踐中,知道只有ASCII字符而沒有努力去證明它(例如,字符串化表單只有數字,標點符號和一個簡短的ASCII名稱; - )在這種情況下,直接轉到「僅僅是__str__」的方法是非常典型的(但如果我與之合作的編程團隊提出了一個本地指南以避免這種情況,那麼我會對該提案採用+1,因爲它很容易在這些問題上犯錯,「不成熟的優化是編程中所有邪惡的根源」;-)。

+2

在蟒蛇2.6.2,最近我絆倒了,因爲實例一個特定的內置Exception子類給出了str(e)和unicode(e)的不同結果。 str(e)給出了用戶友好的輸出; unicode(e)給出了不同的,用戶不友好的輸出。 這是否被認爲是越野行爲? 該類是UnicodeDecodeError;爲了避免混淆,我沒有預先命名它 - 這個例外與unicode相關的事實並不特別相關。 – 2012-03-14 23:50:17

0

如果您在這兩個python2和python3在Django的工作,我建議python_2_unicode_compatible裝飾:

Django提供了一種簡單的方法來定義STR()和的Unicode(),它工作在方法Python 2和Python 3:您必須定義一個str()方法返回文本並應用python_2_unicode_compatible()修飾符。

正如前面對另一個答案的評論所指出的,future.utils的某些版本也支持這個裝飾器。在我的系統中,我需要爲python2安裝更新的未來模塊,併爲python3安裝未來版本。在此之後,那麼這裏是一個功能例如:

#! /usr/bin/env python 

from future.utils import python_2_unicode_compatible 
from sys import version_info 

@python_2_unicode_compatible 
class SomeClass(): 
    def __str__(self): 
     return "Called __str__" 


if __name__ == "__main__": 
    some_inst = SomeClass() 
    print(some_inst) 
    if (version_info > (3,0)): 
     print("Python 3 does not support unicode()") 
    else: 
     print(unicode(some_inst)) 

下面是示例輸出(其中venv2/venv3是的virtualenv實例):

~/tmp$ ./venv3/bin/python3 demo_python_2_unicode_compatible.py 
Called __str__ 
Python 3 does not support unicode() 

~/tmp$ ./venv2/bin/python2 demo_python_2_unicode_compatible.py 
Called __str__ 
Called __str__