在python中覆盖内置类型__str__方法

时间:2016-09-19 13:21:20

标签: python python-2.7 python-3.x decode built-in

我需要将一些代码从Python2移植到Python3,主要问题似乎是字节类型,因为str(bytes)给我b'%s'结果,但需要'%s',所以我决定覆盖__str__()字节类的方法,以准确打印我想要的内容。

我尝试使用从字节继承的类修补builtins.bytes,但这似乎只适用于一个文件而不适用于整个项目,也不会影响字节文字(b'')。 / p>

如果从py2到py3有任何其他方式(不那么痛苦),那么很高兴看到它们。

使用.decode('UTF-8')是不可接受的,因为项目超过4k行,并且将解码方法添加到所有必要的位置会导致渐进式错误计数,并且还有一些.decode个位置在3第二方图书馆。

我试着这样做:

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

1 个答案:

答案 0 :(得分:2)

带有文本的规则是“在输入时解码,在输出上编码”。尽管已经做了很多工作来使编写兼容v2和v3的代码变得更容易,但总会出现一些差异,而且Python 3不再定义unicode符号的事实是它们。

尝试在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中都有效。

如果在输入上正确解码,则不必插入许多调用来解码,并且只需要在必须将字符串传递给某种外部工具时进行编码。