Python
Python è un linguaggio a tipizzazione dinamica.
In Python tutto è un oggetto, anche le classi.
Operazioni
Le operazioni disponibili sono le seguenti:
+, -, * # Addizione, sottrazione e moltiplicazione
/ # Divisione (risultato comunque convertito a float)
** # Elevamento a potenza
//, % # Quoziente e resto
a >> n, a << n # Shift dx/sx di n posizioni di a
a & b, a | b # And/or bitwiseObject oriented programming in python
Essendo tutto una classe in python, ci deve essere un punto di singolarità da cui tutto parte, e questo punto è type.
type
La classe type ha come tipo se stessa.
type(type) # <class 'type'>
print(type.__class__) # stesso risultato di sopraNon ha senso parlare di attributi o variabili di classe o di istanza, perchè esistono solo oggetti e i loro attributi.
Se gli oggetti sono classi, le istanze non hanno particolari diritti sugli attributi.
Accesso agli attributi
L’accesso agli attributi è diverso da linguaggi come Java.
class foo:
s = 0
def get(self):
return s
def somma(self, y, x):
s = x+yIl problema di questo codice è che la funzione get() restituisce un errore, in quanto l’attributo s non viene trovato. Questo perchè nel namespace locale non c’è, e nemmeno in quello enclosing. Quindi, se ci fosse un’assegnazione (come in somma) sarebbe a livello locale. Dal momento che vuole recuperare il valore, viene lanciato un errore.
Infatti, se si chiama la funzione somma, l’assegnazione interna è a livello locale, quindi:
f = foo()
f.somma(2, 3)
f.s # s = 0Se si prova ad accedere ad un attributo, come nella funzione get, solo attraverso il suo identificativo, il compilatore lo cerca tramite il principio LEGB. Se invece si prova ad accedere ad un attributo tramite l’oggetto nel quale è contenuto, come ad esempio O.s, l’oggetto O viene risolto tramite LEGB, e poi si cerca l’attributo nell’oggetto tramite catena ereditaria in cui l’oggetto è inserito.
Ricerca attributi
Il tipo di ricerca dipende da come si cerca di accedere all’attributo. Se si cerca di accedere ad un attributo tramite O.a, allora si cerca prima O, e poi si cerca l’attributo.
Override di attributi
Se più superclassi di una classe A definiscono un attributo con lo stesso nome, A vedrà solo l’attributo della classe che compare prima nell’MRO. Si applica anche a funzioni con lo stesso nome, anche se hanno signature differente.
Python non supporta l’overloading di metodi.
Variabili statiche
class foo:
s = 0
def get(self):
return foo.s
def somma(self, y, x):
foo.s = x+yQui l’attributo classe s viene usato da tutte le istanze di foo, quindi è paragonabile ad un attributo statico.
Metodi bound e unbound
I metodi bound sono metodi chiamati da un’istanza della classe, e ai quali questa istanza viene legata, per non perdere il legame. L’istanza viene passata automaticamente dal compilatore come primo parametro.
I metodi unbound, invece, vengono chiamati a livello di classe, e nessuna istanza viene passata come parametro.
Ereditarietà
Una classe A è superclasse di B, se A è una classe base di B o se A è una classe base di una superclasse di B.
class A:
pass
class B(A):
pass
class C(B):
passA è superclasse sia di B che di C, e B è superclasse di C.
Si può anche dire che A è antenato di B, e B è discendente di A.
Come già visto, Python supporta anche l’Ereditarietà multipla. Per gestire l’Ereditarietà multipla, che può essere vista come un grafo, si utilizza MRO.