替换Python中列表对象上的_str__方法

替换Python中列表对象上的_str__方法,python,Python,这似乎应该很简单: 我想要一个列表,就像其他任何列表,除了它有一个不同的\uuuu str\uuuu方法 试图设置对象。\uuuu str\uuu=foo将导致只读错误 试图将list子类化意味着您需要某种方法将现有的list转换为子类的实例。这需要手动复制所有属性(非常痛苦),或者以某种方式自动复制所有属性,我不知道怎么做 试图在列表对象周围编写一个包装器意味着我必须找到某种方法将所有消息发送到包装对象,除了我用自己的方法处理的。\uuu str\uuu。我不知道怎么做 非常感谢任何备选方案或

这似乎应该很简单:

我想要一个
列表
,就像其他任何
列表
,除了它有一个不同的
\uuuu str\uuuu
方法

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

  • 非常感谢任何备选方案或解决方案#2或#3。谢谢

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

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

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

    我是一名Java程序员,但我认为这正是您想要的(用Python 2.6测试):

    类myList(列表): ... 定义(自我): ... 返回“aaa” ... >>>def myListWrapper(列表): ... 返回myList(列表) ... >>>a=[1,2,3] >>>类型(a) >>>b=myListWrapper(a) >>>类型(b) >>>印刷品(a) [1, 2, 3] >>>印刷品(b) aaa
    如何包装列表

    >>> class StrList(object):
        def __init__(self, data=None):
            self._data = data or []
        def __str__(self):
            return "StrList!"
        def __getattr__(self, attr):
            if attr == "_data":
                return self.__dict__[attr]
            return getattr(self._data, attr)
        def __setattr__(self, key, val):
            if key == "_data":
                self.__dict__[key] = val
            else:
                setattr(self._data, key, val)
        def __getitem__(self, index):
            return self._data[index]
        def __setitem__(self, index, value):
            self._data[index] = value
    
    
    >>> l = StrList(range(3))
    >>> print l
    StrList!
    >>> l[0]
    0
    >>> for x in l:
        print x
    
    
    0
    1
    2
    >>> l[0] = "spam"
    >>> l.append("egg")
    >>> print list(l)
    ['spam', 1, 2, 'egg']
    >>> 
    

    这就提出了一个问题:为什么要覆盖_str____)方法

    创建一个类来封装对象不是更好吗

    class MyContainer(object):
        def __init__(self, list):
            self.containedList = list
    
        def __str__(self):
            print('All hail Python')
    
    这样,您就不必担心转换对象、复制属性等问题。(顺便问一下,MyList(longlist)有多贵?它是一个智能复制,还是一个愚蠢的“让我们从iterable重新创建一个list对象?”)


    如果,在某个时刻,做你想做的事情看起来很复杂,这可能意味着你做错了:p

    这个解决方案在没有包装的情况下工作。如果通过“添加”将两个列表连接起来,则有效。任何修改列表本身的操作都将按预期工作。只有返回列表副本的函数(如: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])
    

    如果要为其他容器(例如,
    元组
    )覆盖
    \uuu str\uuu
    ,可以利用多重继承:

    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))
    
    “福”

    “福”


    我先前的评论作为答案。正如您所看到的,MyList接受其构造函数中的任何序列。

    您不能修改list的str:>>>list([1,2,3])。\uuuu str\uuuu=myString回溯(最近一次调用):AttributeError中第1行的文件“”:“list”对象属性“str”是只读的。但是继承可以很好地完成。这似乎很接近,但是如何将
    列表
    转换为
    myList
    ?例如,我从一份清单中得到了一份清单。现在我该怎么办?这个答案很神秘。“编辑:我的坏”是怎么回事?你能把这个问题修正为一个独立的答案,不需要阅读问题或其他答案的评论吗?在SO中没有“上面”,因为答案顺序会随着选票的变化而变化。实际上,这是一个评论,所以它仍然在上面。但是你是第二个要求独立回答的人,所以…回答2。转换现有列表是自动完成的,因为列表是iterable,并且列表构造函数采用iterable。试一下myList(whateverList)。有什么原因不能用myList开始吗?或者,考虑写一个环绕一个列表的函数,所以你称之为PrPyTyPrimtListListar(the Sype Listar),而不是STR(the SyLIST)@ SaffsD:这是可行的,但是你必须记住要一直打印而不是打印,这是我试图避免的。“Matthew Flaschen:太棒了!这似乎有效!你应该把这些写下来,我会投票表决的。谢谢非常好,谢谢。我不知道myList(list)会自动将list实例中的所有数据复制到myList实例中。我认为这只是因为list的实现者显式地创建了一个类似复制构造函数的函数,而不是因为这是所有继承的通用函数。当然,进一步的问题是,编写完成所有复制的函数需要做多少工作。他们必须手动复制每个属性吗?list类有一个构造函数“list(sequence)->new list initialized from sequence's items”myListWrapper接受一个list对象并返回一个myListWrapper,这是一个危险的解决方案。如果运行任何在myList上返回新列表的列表操作,结果将是一个本机python列表。例如myList()+myList(),这很有趣,但老实说,我不明白示例中的l.append为什么或如何工作。是什么告诉它如何将调用从StrList传递到其中的列表中的append?当您使用对象没有的方法/成员调用对象时,会调用getattr。然后,我们可以将该调用传递到包装列表。同样的情况也适用于setattr等人。但是,您必须重写对“_data”的调用,以避免无限递归。如果您封装而不是子类化,则不会免费获得所有列表功能,除非您a)重写MyContainer上的所有列表方法,或者b)必须始终调用到container_instance.containedList中。如果我有一个复杂的对象,并且碰巧需要一个列表(例如,类需要一个列表、一个字符串、几个整数等等),那么这将是一个更好的解决方案。但我所需要的只是对列表稍加修改。这很吸引人,也很棒。我认为完整的解决方案需要覆盖所有操作符方法。我想知道需要做些什么才能把它们分类并反过来工作(不过这不是你需要回答的问题)。谢谢您可能想更换fi
    Ex = ["a", 2, 4] #our_list
    Ex(-1) = "xuxu_beleza" #the_name_of_your_list(index) = new_item 
    Print(Ex) 
    ["a", 2, "xuxu_beleza"] #our_new_list
    
    **list[index] = new_item**
    
    class MyList(list):
         def __str__(self):
                 return "foo"
    
    str(MyList([1, 2, 3]))
    
    str(MyList(list([1, 2, 3])))
    
    Ex = ["a", 2, 4] #our_list
    Ex(-1) = "xuxu_beleza" #the_name_of_your_list(index) = new_item 
    Print(Ex) 
    ["a", 2, "xuxu_beleza"] #our_new_list
    
    **list[index] = new_item**