Estendendo classes base em Python

votos
10

Eu estou tentando estender algumas classes base em Python:

class xlist (list):
    def len(self):
        return len(self)

    def add(self, *args):
        self.extend(args)
        return None


class xint (int):
    def add(self, value):
        self += value
        return self


x = xlist([1,2,3])
print x.len()   ## >>> 3 ok
print x         ## >>> [1,2,3] ok
x.add (4, 5, 6)
print x         ## >>> [1,2,3,4,5,6] ok

x = xint(10)
print x         ## >>> 10 ok
x.add (2)
print x         ## >>> 10  # Not ok (#1)

print type(x)         ## >>> <class '__main__.xint'> ok
x += 5
print type(x)         ## >>> <type 'int'>  # Not ok (#2)

Ele funciona muito bem na lista caso, porque o acréscimo método modifica o objeto no lugar, sem devolvê-lo. Mas no int caso, o add método não modifica o valor do externo x variável. Acho que isso é bom no sentido de que a auto é uma variável local no add método da classe, mas isso está me impedindo de modificar o valor inicial atribuído à instância da classe.

É possível estender uma classe desta forma ou devo definir uma propriedade de classe com o tipo de base e mapear todos os métodos necessários para esta propriedade?

Publicado 28/08/2008 em 23:18
fonte usuário
Em outras línguas...                            


4 respostas

votos
23

Seus dois xintexemplos não funcionam por duas razões diferentes.

O primeiro não funciona porque self += valueé equivalente ao self = self + valueque acaba de reatribui a variável local selfa um objeto diferente (um inteiro), mas não altera o objeto original. Você realmente não pode obter este

>>> x = xint(10)
>>> x.add(2)

para trabalhar com uma subclasse de intdesde inteiros são imutáveis .

Para obter o segundo para trabalhar, você pode definir um __add__método , assim:

class xint(int):
    def __add__(self, value):
        return xint(int.__add__(self, value))

>>> x = xint(10)
>>> type(x)
<class '__main__.xint'>
>>> x += 3
>>> x
13
>>> type(x)
<class '__main__.xint'>
Respondeu 29/08/2008 em 00:41
fonte usuário

votos
5

int é um tipo de valor, de modo que cada vez que você faz uma atribuição, (por exemplo, ambas as instâncias do + = acima), ela não modifica o objeto que você tem na pilha, mas substitui a referência com um dos o resultado da mão direita lado da atribuição (isto é, um int)

lista não é um tipo de valor, de modo que não está sujeito às mesmas regras.

esta página tem mais detalhes sobre as diferenças: http://docs.python.org/ref/objects.html

IMO, sim, você deve definir uma nova classe que mantém um int como uma variável de instância

Respondeu 28/08/2008 em 23:32
fonte usuário

votos
2

i expandiu você Xlist classe um pouco, fez isso para que você pode encontrar todos os pontos de índice de um número tornando-se assim que você pode estender com várias listas ao mesmo tempo tornando-se inicializar e tornando-se assim que você pode interagir com ele

class xlist:
    def __init__(self,alist):
        if type(alist)==type(' '):
            self.alist = [int(i) for i in alist.split(' ')]
        else:
            self.alist = alist
    def __iter__(self):
        i = 0
        while i<len(self.alist):
            yield self.alist[i]
            i+=1
    def len(self):
        return len(self.alist)
    def add(self, *args):
        if type(args[0])==type([1]):
            if len(args)>1:
                tmp = []
                [tmp.extend(i) for i in args]
                args = tmp
            else:args = args[0]
        if type(args)==type(''):args = [int(i) for i in args.split(' ')] 
        (self.alist).extend(args)
        return None
    def index(self,val):
        gen = (i for i,x in enumerate(self.alist) if x == val)
        return list(gen)
Respondeu 24/07/2011 em 21:30
fonte usuário

votos
0

Ints são imutáveis ​​e você não pode modificá-los no lugar, então você deve ir com a opção # 2 (porque a opção # 1 é impossível sem alguns truques).

Respondeu 28/08/2008 em 23:28
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more