Pregunta

Esta parece que debería ser simple:

quiero un list como cualquier otro list, excepto que tiene un método .__str__ diferente.

  1. Tratar de establecer resultados object.__str__ = foo en un error de sólo lectura
  2. Tratando de subclase list significa que necesita alguna manera de convertir un list existente a una instancia de la subclase. Esto requiere o bien copiar todos los atributos manualmente (un enorme dolor), o de alguna manera de copiar todos ellos de forma automática, lo que no sé cómo hacerlo.
  3. tratando de escribir una envoltura alrededor del objeto list significa que tengo que encontrar alguna manera de enviar todos los mensajes al objeto envuelto excepto .__str__ la que yo manejo mi propio método. No sé cómo hacer esto.

Cualquier alternativas o soluciones # 2 o # 3 apreciado considerablemente. Gracias!

¿Fue útil?

Solución

Esta solución funciona sin envoltura. Y funciona si se une a dos listas por el complemento. Cualquier operación que modifique la lista en sí funcionará como se espera. Sólo las funciones que devuelven una copia de la lista como: ordenados, reveresed devolverá la lista de Python nativo que está muy bien. clasificar y revertir, por otra parte operan en la lista en sí y mantendrán el tipo.

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

Otros consejos

Si desea para anular __str__ para otros recipientes (por ejemplo, tuple), se puede tomar ventaja de la herencia múltiple:

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

Se puede extender la clase lista y anularlo:

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

Edit:. Eliminado una parte incorrecta de la respuesta que sugería dinámicamente reemplazando __str__ en el objeto de lista, que no está permitido en la aplicación de listas de Python

Soy un programador de Java, pero creo que es lo que quiere (probado con 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]))

foo

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

foo

Mis comentarios anteriores como una respuesta. Como se puede ver MyList acepta cualquier secuencia en su constructor.

Lo que plantea la pregunta: ¿por qué quieres reemplazar el método __str__

No sería mejor crear una clase para encapsular el objeto?

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

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

De esta manera usted no tiene que preocuparse por la conversión de su objeto, o copiar los atributos, o sea. (Por cierto, lo caro que es Mi lista (longlist)? ¿Es una copia inteligente, o un tonto "vamos a volver a crear un objeto de lista de un iterable?")

Si, en algún momento, se ve complicado de hacer lo que estás tratando de hacer, podría significar que usted está haciendo mal: p

¿Qué hay de envolver la lista?

>>> 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**
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top