簡體   English   中英

在Python中替換list對象上的__str__方法

[英]Replace __str__ method on list object in Python

這看起來應該很簡單:

我想要一個像任何其他list一樣的list ,除了它有一個不同的.__str__方法。

  1. 嘗試設置object.__str__ = foo導致只讀錯誤
  2. 嘗試子類list意味着您需要某種方法將現有list轉換為子類的實例。 這需要手動復制所有屬性(一個巨大的痛苦),或以某種方式自動復制它們,我不知道該怎么做。
  3. 試圖在list對象周圍編寫一個包裝器意味着我必須找出一些方法將所有消息發送到包裝對象,除了.__str__ ,我用自己的方法處理。 不知道該怎么做。

任何替代方案,或解決方案#2或#3非常感謝。 謝謝!

此解決方案無需包裝即可運行。 如果您通過添加加入兩個列表,則可以使用。 任何修改列表本身的操作都將按預期工作。 只有返回列表副本的函數如:sorted,reveresed將返回本機python列表,這很好。 另一方面,排序和反向操作列表本身並保持類型。

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

您可以擴展列表類並覆蓋它:

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

編輯:刪除了答案的錯誤部分,建議動態替換列表對象上的__str__ ,這在Python列表的實現中是不允許的。

如果要為其他容器(例如, 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))

我是Java程序員,但我認為這就是你想要的(用python 2.6測試):

>>> class myList(list):
...   def __str__(self):
...     return "aaa"
...
>>> def myListWrapper(list):
...   return myList(list)
...
>>> a = [1, 2, 3]
>>> type(a)
<type 'list'>
>>> b = myListWrapper(a)
>>> type(b)
<class '__main__.myList'>
>>> print(a)
[1, 2, 3]
>>> print(b)
aaa
class MyList(list):
     def __str__(self):
             return "foo"

str(MyList([1, 2, 3]))

“富”

str(MyList(list([1, 2, 3])))

“富”

我之前的評論作為答案。 如您所見,MyList接受其構造函數中的任何序列。

提出了一個問題:為什么要覆蓋__str__方法?

創建一個類來封裝你的對象不是更好嗎?

class MyContainer(object):
    def __init__(self, list):
        self.containedList = list

    def __str__(self):
        print('All hail Python')

這樣您就不必擔心轉換對象或復制屬性,或者無論如何。 (順便說一句,MyList(longlist)有多貴?是智能副本,還是愚蠢的“讓我們從迭代中重新創建一個列表對象?”)

如果在某些時候,做你正在做的事情看起來很復雜,那可能意味着你做錯了:p

如何包裝清單?

>>> 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']
>>> 
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**

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM