Domanda

Questo sembra che dovrebbe essere semplice:

voglio un list come qualsiasi altro list, eccetto che ha un metodo .__str__ diverso.

  1. Il tentativo di impostare i risultati object.__str__ = foo in un solo errore di lettura
  2. Il tentativo di creare una sottoclasse list significa che è necessario un modo per convertire un list esistente a un'istanza della sottoclasse. Questo richiede o la copia di tutti gli attributi manualmente (un dolore enorme), o in qualche modo la copia di tutti automaticamente, che non so come fare.
  3. Il tentativo di scrivere un wrapper per l'oggetto list significa che devo capire un modo per inviare tutti i messaggi per l'oggetto avvolto tranne .__str__ che gestisco con mio metodo. Non so come fare questo.

Le eventuali alternative o soluzioni # 2 o # 3 molto apprezzato. Grazie!

È stato utile?

Soluzione

Questa soluzione funziona senza un involucro. E funziona se si uniscono due liste da add. Qualsiasi operazione che modifica la lista stessa funzionerà come previsto. Solo le funzioni che restituiscono una copia della lista come: ordinato, reveresed restituirà la lista di pitone nativa che va bene. ordinamento e invertire dall'altro operano nella lista stessa e manterrà il 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])

Altri suggerimenti

Se si desidera sovrascrivere __str__ per altri contenitori (ad esempio, tuple), è possibile usufruire di ereditarietà multipla:

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

Si potrebbe estendere la classe lista e ignorarlo:

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

Modifica:. Rimuovere una parte non corretta della risposta che ha suggerito in modo dinamico la sostituzione __str__ sull'oggetto lista, che non è consentita nella realizzazione di liste Python

Sono un programmatore Java, ma penso che è ciò che si vuole (testato 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'

I miei precedenti commenti come una risposta. Come si può vedere MyList accetta qualsiasi sequenza nel suo costruttore.

Il che solleva la questione: perché vuoi sovrascrivere il metodo __str__

Non sarebbe meglio creare una classe per incapsulare il vostro oggetto?

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

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

In questo modo non c'è bisogno di preoccuparsi di convertire l'oggetto, o copiare gli attributi, o qualunque. (A proposito, quanto costoso è MyList (longlist)? E 'una copia intelligente, o uno stupido "cerchiamo di ricreare un oggetto elenco da un iterabile?")

Se, ad un certo punto, sembra complicato per fare quello che stai cercando di fare, potrebbe significare che si sta facendo male: p

Come su avvolgendo 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**
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top