Utvide grunnklasser i Python

stemmer
10

Jeg prøver å utvide noen base klasser i 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)

Det fungerer fint i listen saken fordi append metoden endrer objektet på plass, uten å returnere den. Men i int tilfelle, add gjør metoden ikke endre verdien av den eksterne x variabel. Jeg antar at det er fint i den forstand at selv er en lokal variabel i tillegg metoden til klassen, men dette hindrer meg å modifisere den opprinnelige verdi tilordnet til forekomst av klassen.

Er det mulig å forlenge en klasse på denne måten eller skal jeg definere en klasse eiendom med base type og kartlegge alle nødvendige metoder til dette hotellet?

Publisert på 28/08/2008 klokken 22:18
kilden bruker
På andre språk...                            


4 svar

stemmer
23

Dine to xinteksempler fungerer ikke for to forskjellige grunner.

Den første virker ikke fordi self += valuetilsvarer self = self + valuesom bare reassigns den lokale variable selftil et annet objekt (et helt tall), men endrer ikke det opprinnelige objektet. Du kan egentlig ikke få dette

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

å arbeide med en underklasse av intsiden heltall er uforanderlig .

For å få den andre til å jobbe kan du definere en __add__metode , som så:

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'>
Svarte 28/08/2008 kl. 23:41
kilden bruker

stemmer
5

int er en verditype, slik at hver gang du gjør en oppgave, (f.eks begge tilfeller av + = over), betyr det ikke endrer objektet du har på haugen, men erstatter referanse med en av resultatet av høyre hånd side av oppdraget (dvs. en int)

Listen er ikke en verditype, så det er ikke bundet av de samme reglene.

denne siden har flere detaljer om forskjellene: http://docs.python.org/ref/objects.html

IMO, ja, bør du definerer en ny klasse som holder en int som en instansvariabel

Svarte 28/08/2008 kl. 22:32
kilden bruker

stemmer
2

Jeg utvidet du XList klassen bare litt, gjorde det slik at du kan finne alle indekspoeng i en rekke som gjør det slik at du kan utvide med flere lister samtidig gjør det initial og gjør det slik at du kan iterere gjennom det

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)
Svarte 24/07/2011 kl. 20:30
kilden bruker

stemmer
0

Ints er uforanderlige, og du kan ikke endre dem på plass, så du bør gå med alternativ # 2 (fordi alternativ 1 er umulig uten noen lureri).

Svarte 28/08/2008 kl. 22:28
kilden bruker

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