在Python中替换list对象上的str方法

2024-03-29 00:43:02 发布

您现在位置:Python中文网/ 问答频道 /正文

这看起来应该很简单:

我想要一个list和其他任何list一样,只是它有一个不同的.__str__方法。

  1. 试图设置object.__str__ = foo会导致只读错误
  2. 试图子类化list意味着您需要某种方法将现有的list转换为子类的实例。这需要手动复制所有属性(非常痛苦),或者以某种方式自动复制所有属性,我不知道该怎么做。
  3. 试图在list对象周围编写一个包装器意味着我必须找到某种方法将所有消息发送到包装对象,但使用自己的方法处理的.__str__除外。不知道怎么做。

非常感谢任何替代方案或解决方案2或3。谢谢!


Tags: 对象实例方法消息属性objectfoo错误
3条回答

此解决方案不使用包装器。如果通过add连接两个列表,则有效。任何修改列表本身的操作都将按预期工作。只有像:sorted,reveresed这样返回列表副本的函数才能返回原生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])

如果要重写其他容器的__str__(例如tuple),可以利用多重继承:

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))

您可以扩展list类并覆盖它:

class myList(list):
  def __str__(self):
    # do something
    return "something"

编辑:删除了不正确的答案部分,该部分建议动态替换list对象上的__str__,这在Python列表的实现中是不允许的。

相关问题 更多 >