Question

Cela semble que cela devrait être simple:

Je veux un list comme tout autre list, sauf qu'il a une méthode différente .__str__.

  1. Essayer de définir les résultats de object.__str__ = foo dans une lecture seule erreur
  2. Essayer de sous-classe list signifie que vous devez trouver un moyen de convertir un list existant à une instance de la sous-classe. Cela nécessite soit copier manuellement tous les attributs (une énorme douleur), ou en les copiant tout en quelque sorte automatiquement, que je ne sais pas comment faire.
  3. Essayer d'écrire un wrapper autour de l'objet list signifie que je dois trouver un moyen d'envoyer tous les messages à l'objet enveloppé sauf que je .__str__ poignée avec ma propre méthode. Je ne sais pas comment faire.

Toutes les alternatives ou solutions # 2 ou # 3 grandement appréciés. Merci!

Était-ce utile?

La solution

Cette solution fonctionne sans emballage. Et fonctionne si vous vous joignez deux listes en ajouter. Toute opération qui modifient la liste elle-même fonctionnera comme prévu. Seules les fonctions qui renvoient une copie de la liste comme: triée, reveresed retourne la liste python natif qui est très bien. sorte et inverse d'autre part fonctionnent sur la liste elle-même et gardera le 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])

Autres conseils

Si vous souhaitez remplacer __str__ pour d'autres conteneurs (par exemple, tuple), vous pouvez profiter de l'héritage multiple:

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

Vous pouvez étendre la classe de liste et la remplacer:

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

Modifier. Supprimé une partie incorrecte de la réponse qui a suggéré de remplacer dynamiquement __str__ sur l'objet de la liste, ce qui est interdit dans la mise en œuvre des listes Python

Je suis un programmeur Java, mais je pense que c'est ce que vous voulez (testé avec 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'

Mes premiers commentaires en réponse. Comme vous pouvez le voir MyList accepte toute séquence dans son constructeur.

Ce qui pose la question: pourquoi voulez-vous remplacer la méthode __str__

Ne serait-il préférable de créer une classe pour encapsuler votre objet?

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

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

De cette façon, vous n'avez pas à vous soucier de la conversion de votre objet, ou la copie des attributs, ou que ce soit. (En passant, combien coûte est MyList (longlist)? Est-ce une copie intelligente, ou un muet « Recréons un objet d'une liste itérables? »)

Si, à un moment donné, il semble compliqué de faire ce que vous essayez de le faire, cela pourrait signifier que vous faites mal: p

Que diriez-vous envelopper la liste?

>>> 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**
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top