A Byte of Python

Classes i variables d'objecte

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:

Ús de variables de classe i objecte

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

Sortida

				
$ 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.
				
				

Com funciona

É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.

Nota pels programadors de C++/Java/C#

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.