Pergunta

Isto parece que deve ser simples:

Eu quero um list como qualquer outro list, exceto que ele tem um método .__str__ diferente.

  1. tentar definir resultados object.__str__ = foo em um erro de somente leitura
  2. Tentando meios list subclasse você precisa de alguma maneira de converter um list existente para uma instância da subclasse. Isso requer tanto copiar todos os atributos manualmente (uma dor enorme), ou de alguma forma copiá-los todos automaticamente, o que eu não sei como fazer.
  3. Tentando escrever um invólucro em torno dos meios de objetos list eu tenho que descobrir uma maneira de enviar todas as mensagens para o objeto embrulhado exceto .__str__ que eu lidar com o meu próprio método. Não sei como fazer isso.

Qualquer alternativas ou soluções # 2 ou # 3 muito apreciada. Obrigado!

Foi útil?

Solução

Esta solução funciona sem um wrapper. E funciona se você juntar duas listas por add. Qualquer operação que modifique a lista em si vai funcionar como esperado. Somente funções que retornam uma cópia da lista como: classificado, reveresed retornará a lista python nativa que é bom. tipo e reverter, por outro lado operam sobre a própria lista e manterá o 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])

Outras dicas

Se você gostaria de substituir __str__ para outros recipientes (por exemplo, tuple), você pode tirar vantagem de herança múltipla:

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

Você poderia estender a classe lista e substituí-lo:

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

Edit: removida uma parte incorreta da resposta que sugeriu dinamicamente substituindo __str__ na lista de objeto, o que não é permitido na implementação de listas Python

.

Eu sou um programador Java, mas eu acho que é o que você quer (testado com o 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'

Os meus comentários anteriores como uma resposta. Como você pode ver MyList aceita qualquer sequência em seu construtor.

O que levanta a questão: por que você quer substituir o método __str__

?

Não seria melhor criar uma classe para encapsular o seu objeto?

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

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

Desta forma, você não precisa se preocupar com a conversão de seu objeto, ou copiar os atributos, ou qualquer. (A propósito, o quão caro é MyList (longlist)? É uma cópia inteligente, ou um burro "vamos recriar um objeto de lista de um iterável?")

Se, em algum momento, isso parece complicado para fazer o que você está tentando fazer, isso pode significar que você está fazendo errado: p

Como cerca de embrulho 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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top