Ara que hem parlat de la part funcional de les classes i objectes, anem a considerar la part de les dades. En realitat no hi ha res d'especial. Es tracta de variables normals que s'associen als espais de noms de les classes i objectes. És a dir, els noms d'aquestes dades només són vàlids dins del context d'aquestes classes i objectes.
Hi ha dos tipus de camps: variables de classe i variables d'objecte (o instància). La diferència està en si és la classe o el objecte qui té la variable.
Les variables de classe són compartides en el sentit que poden ser accedides per a qualsevol objecte (instància) d'aquesta classe. Només hi ha una còpia de les variables de classe i quan qualsevol de les instàncies realitza un canvi en aquestes variables, el canvi es reflecteix també a tota la resta d'instàncies.
Les variables d'objecte pertanyen a cada objecte o instància individual. Cada objecte té la seva pròpia còpia del camp. És a dir, no estan compartides ni estan relacionades de cap manera amb el camp amb el mateix nom a una instància diferent de la mateixa classe. Estudiem el següent exemple per a clarificar-nos:
Example 11.4. Ús de variables de classe i objecte
#!/usr/bin/python # Filename: objvar.py class Person: '''Representa una persona.''' population = 0 def __init__(self, name): '''Inicialitza les dades de persona.''' self.name = name print '(Initializing %s)' % self.name # Quan la persona es crea, s'afegeix a la població. Person.population += 1 def __del__(self): '''Elimina la instància''' print '%s says bye.' % self.name Person.population -= 1 if Person.population == 0: print 'I am the last one.' else: print 'There are still %d people left.' % Person.population def sayHi(self): '''Saludant. Realment això és el que fa.''' print 'Hi, my name is %s.' % self.name def howMany(self): '''Escriu la població actual.''' if Person.population == 1: print 'I am the only person here.' else: print 'We have %d persons here.' % Person.population swaroop = Person('Swaroop') swaroop.sayHi() swaroop.howMany() kalam = Person('Abdul Kalam') kalam.sayHi() kalam.howMany() swaroop.sayHi() swaroop.howMany()
$ python objvar.py (Initializing Swaroop) Hi, my name is Swaroop. I am the only person here. (Initializing Abdul Kalam) Hi, my name is Abdul Kalam. We have 2 persons here. Hi, my name is Swaroop. We have 2 persons here. Abdul Kalam says bye. There are still 1 people left. Swaroop says bye. I am the last one.
És un exemple llarg però ajuda a demostrar la natura de les variables
de classe i objecte.
La variable population
pertany a la classe
Person
i, per tant, és una variable dee classe.
El camp name
pertany a l'objecte i, per tant, és
una variable d'objecte.
Ens referim a la variable de classe population
com a Person.population
i no com a
self.population
.
Atenció: una variable d'objecte amb el mateix nom que una variable de
classe amagarà la variable de classe.
Per referenciar la variable d'objecte name
fem servir la notació self.name
.
Cal que recordem aquesta simple diferència entre variables de classe
i objecte.
Hem fet servir el mètode __init__
per a inicialitzar la instància de Person
amb un nom. Aquest mètode, incrementa la variable
population
en un ja que hem creat una nova instància
de Person.
Per altra banda, el valor de self.name
és
específic de cada instància.
Recordem que cal fer servir self
per a referir-se
a les variables i mètodes del mateix objecte. D'això en diem
referència d'atribut.
Al programa veiem també l'ús de docstrings
tant per classes com per mètodes.
Podem accedir al docstring d'una classe o mètode en temps d'execució usant
els mètodes
Person.__doc__
i
Person.sayHi.__doc__
Un altre mètode especial és __del__
. Aquest
és cridat quan l'objecte mor. És a dir, quan no serà usat mai més i
l'espai que ocupa és retornat al sistema per que pugui ser reutilitzat.
Al nostre programa simplement decrementem en un el valor de la propietat
Person.population
.
El mètode __del__
s'executa quan
quan l'objecte sigui eliminat. Si volem fer-ho explícitament, ens
caldrà fer servir la sentència del
que ja hem vist
anteriorment.
Per Python, tots els membres de les classes (incloent els camps) tenen visibilitat public i els mètodes són virtual.
Hi ha una excepció: en cas que fem servir camps amb noms que tinguin
com a prefix el doble guió baix com a
__privatevar
, Python retalla el nom de manera que
la variable queda privada.
Per convenció, qualsevol variable que ha de fer-se servir només dins de la classe, començarà amb guió baix, i la resta dels noms són públics i poden ser usats des d'altres classes/objectes. Amb tot, això és només una convenció. Python no controla l'accés a una variable que comença amb un guió baix (excepte quan són dos seguits).
Tinguem també present que el mètode __del__
és l'equivalent al concepte de destructor.