在Python中替换列表对象的__str__方法
这看起来应该很简单:
我想要一个 list
,和其他的 list
一样,只是它的 .__str__
方法不一样。
- 尝试用
object.__str__ = foo
来设置时,结果出现了只读错误。 - 如果想要继承
list
,那就需要有办法把一个现有的list
转换成这个子类的实例。这就需要手动复制所有属性(这太麻烦了),或者以某种方式自动复制所有属性,但我不知道怎么做。 - 如果想要在
list
对象周围写一个包装器,那我就得想办法把所有消息都发送给被包装的对象,除了.__str__
,这个我用自己的方法来处理。我不知道怎么做到这一点。
任何替代方案,或者解决方案 #2 或 #3 都非常感谢。谢谢!
8 个回答
5
你可以扩展列表类,并重写它:
class myList(list):
def __str__(self):
# do something
return "something"
补充说明:删除了答案中一个不正确的部分,之前提到可以动态替换列表对象的 __str__
,但在Python列表的实现中这是不允许的。
7
如果你想要为其他容器(比如说 tuple
)重写 __str__
方法,你可以利用多重继承的特性:
class PrettyStr(object):
def __str__(self):
ret = ''
if isinstance(self, (list, tuple)):
ret = ''.join(str(elem) for elem in self)
else:
pass # handle other types here
return ret
class MyList(PrettyStr, list):
pass
class MyTuple(PrettyStr, tuple):
pass
if __name__ == "__main__":
print MyList([1, 2, 3, 4])
print MyTuple((1, 2, 3, 4))
13
这个解决方案不需要额外的包装就能正常工作。而且如果你用加法把两个列表合并在一起,它也能正常运作。任何会修改列表本身的操作都会按预期工作。只有那些返回列表副本的函数,比如:sorted(排序)和reversed(反转),会返回原生的Python列表,这样也是可以的。另一方面,sort(排序)和reverse(反转)是直接在列表上操作的,它们会保持列表的类型。
class myList(list):
def __new__(cls, data=None):
obj = super(myList, cls).__new__(cls, data)
return obj
def __str__(self):
return 'myList(%s)' % list(self)
def __add__(self, other):
return myList(list(self) + list(other))
>>> l = myList(range(5))
>>> print l
myList([0, 1, 2, 3, 4])
>>> print l + [1, 2]
myList([0, 1, 2, 3, 4, 1, 2])
>>> l.sort()
>>> print l
myList([0, 1, 2, 3, 4])