Subtyping

Dal momento che le classi base non si possono modificare (aggiungere attributi principalmente o modificarli), solitamente si utilizzano come superclassi per altre classi definite dallo sviluppatore.

Iterazione per la versione migliore

Per la rappresentazione di un oggetto quando si stampa, esistono due Magic methods:

  • __str__: viene utilizzato quando si chiama un oggetto object
  • __repr__: viene utilizzato quando si utilizza print(object)

In fondo alla pagina si possono trovare le versioni 1 e 2 per compararle alla versione finale.

v3

class Point(tuple):
	def __new__(cls, x, y):
		error = False
		try:
			1+x+y
		except TypeError:
			error = True
		if error:
			raise PointException("The coordinates must be numbers")
		return super().__new__(cls, (x, y))

Andando ad utilizzare __new__, si va ad agire alla creazione dell’oggetto stesso, e quindi si può avere un codice molto più pulito. Questa versione ha come superclasse una tupla, ma l’istanziazione viene eseguita come ci si aspetterebbe con due parametri, e non una tupla.

p = Point(1, 2)

Somma tra due punti

Possiamo gestire anche la somma tra due punti, in modo da farla avvenire come somma tra vettori

# nella classe Point si può avere un metodo __add__
 
def __add__(self, right):
	return Point(self[0]+right[0], self[1]+right[1])

v1

class PointException(Exception):
	pass
	
class Point:
	def __init__(self, x, y):
		error = False
		try:
			1+x+y
		except TypeError:
			error = True
		if error:
			raise PointException("The coordinates must be numbers")
		self.x = x
		self.y = y
	
	def __str__(self):
        return f"({self.x},{self.y})"
    def __repr__(self):
        return f"point2D({self.x},{self.y})"

Il problema di questa versione è che non si sfrutta nessuna qualità della tupla, perché alla fine un punto è una tupla.

v2

class Point(tuple):
	def __init__(self, coordinates):
		if len(coordinates) != 2:
			raise PointException("The coordinates must be 2")
		
		error = False
		try:
			sum(coordinates)
		except TypeError:
			error = True
		if error:
			raise PointException("The coordinates must be numbers")

Questa versione ha come parametri lo stesso identico oggetto duplicato (self e coordinates sono etrambi la stessa tupla), e bisogna istanziarla con una tupla come parametro.

p = Point((1, 2))

python_book4