2016-09-19 48 views
1

我需要將一些代碼從Python2移植到Python3,主要問題似乎是字節類型,因爲str(字節)給我b'%s'結果,但需要'%s',所以我決定覆蓋__str__()字節類的方法來打印我想要的。Python中覆蓋內建類型__str__方法

我試圖修補builtins.bytes從字節繼承的類,但似乎只適用於一個文件,而不是整個項目,也不影響字節文字(b'')。

如果有任何其他方式(不太痛苦)從py2移植到py3,很高興看到它們。

使用.decode('UTF-8')是不可接受的,因爲該項目超過4k行,並且將解碼方法添加到所有必需的位置會導致漸進式錯誤計數,還有一些.decode位置在第三方庫中。

我試圖做這樣的事情:

import builtins 

class StrBytes(builtins.bytes): 
    def __str__(self): 
     return self.decode('UTF-8') 

builtins.bytes = StrBytes 

然後,如果我用bytes()它創建StrBytes對象和str(bytes())正是我想要的。這樣是不好的,因爲它不包括構建個字節從字面字節對象:

>>> type(bytes()) 
    <class 'StrBytes'> 

>>> type(b'') 
    <class 'bytes'> 

而且我不能肯定它是否適合整個項目,而不是隻有一個文件。

在我的代碼中的許多不同的地方,我有這樣的事情:

return b''.join(some_extra_values) 

keys = [b'1', b'2', b'3'] # actually keys are given from another part of code 
for key in keys: 
    some_dict[key] = some_value 

some_dict['1'] # works in py2, not in py3, KeyError 
+0

可以請你發佈一個可執行的,自包含的例子嗎? – dm03514

+0

請您[編輯您的問題](https://stackoverflow.com/posts/39574286/edit)包含您需要轉換的一行代碼的示例,以及除了decode()之外您嘗試過的內容。 '? – cxw

回答

2

文本的規則是「解碼輸入,編碼輸出。」雖然已經做了很多工作來使編寫v2和v3兼容的代碼更容易,但總會有一些差異,並且Python 3不再定義符號的事實就是其中之一。

在Python中嘗試修補內置類型並不是一個好主意。因爲它們在C中定義,所以沒有有效的方法來修補它們的方法。

一個可能有用的工具是

from __future__ import unicode_literals 

時,當該程序將解釋所有字符串文字爲Unicode字符串,而不是字節串的開頭插入。

調整代碼的另一種方法是使用這樣一個事實,即Python 3不實現unicode名稱來驅動功能檢測。所以,你可以寫,例如

try: 
    unicode = unicode # RHS raises NameError on Python 3 
except NameError: 
    unicode = str 

然後你可以檢查文本類型寫

if type(s) is unicode: 
    ... 

和比較應該在這兩個v2和v3工作。

如果您在輸入上正確解碼,則不應該插入許多調用來解碼,並且只需要在必須將字符串傳遞給某種外部工具時進行編碼。

+0

我已經在使用unicode_literals,但Py3問題存在於所有字符串的b'前綴,因爲一些第三方庫使用b''。join(...)方式來構造它們的輸出。所以我認爲修補builtin比修補整個代碼更容易。 – Sindbag