Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace __str__ method on list object in Python

Tags:

python

This seems like it should be simple:

I want a list like any other list, except it has a different .__str__ method.

  1. Trying to set object.__str__ = foo results in a read-only error
  2. Trying to subclass list means you need some way to convert an existing list to an instance of the subclass. This requires either copying all attributes manually (a huge pain), or somehow copying them all automatically, which I don't know how to do.
  3. Trying to write a wrapper around the list object means I have to figure out some way to send all messages to the wrapped object except .__str__ which I handle with my own method. Don't know how to do this.

Any alternatives, or solutions #2 or #3 greatly appreciated. Thanks!

like image 293
elliot42 Avatar asked May 31 '09 09:05

elliot42


2 Answers

This solution works without a wrapper. And works if you join two lists by add. Any operation that modify the list itself will work as expected. Only functions that return a copy of the list like: sorted, reveresed will return the native python list which is fine. sort and reverse on the other hand operate on the list itself and will keep the type.

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])
like image 177
Nadia Alramli Avatar answered Oct 09 '22 01:10

Nadia Alramli


If you would like to override __str__ for other containers (e.g., tuple), you can take advantage of multiple inheritance:

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))
like image 31
Bastien Léonard Avatar answered Oct 09 '22 01:10

Bastien Léonard