lettura facile

Attributi privati in una classe di Python

In questa lezione parliamo degli attributi privati in una classe di Python.

Cos'è un attributo privato? In Python, un attributo privato è solitamente definito come un attributo che non dovrebbe essere accessibile direttamente dall'esterno della classe.

In Python, la privacy degli attributi in una classe non è rigorosa come in altri linguaggi di programmazione come Java o C++.

In Python, gli attributi privati si basano più su una convenzione, ovvero su un accordo tra i programmatori, piuttosto che su meccanismi di forzatura rigidi.

Per indicare che un attributo è privato, si utilizza un underscore (`_`) o doppio underscore (`__`) prima del nome dell'attributo.

Singolo underscore

Un singolo underscore prima del nome di un attributo, come `_variabile`, è un segnale per i programmatori che la variabile è destinata ad essere usata solo all'interno della classe o del modulo dove è definita.

Tuttavia, è solo una convenzione e non impedisce l'accesso diretto all'attributo.

Ad esempio, definisci questa classe

class Poligono:
    def __init__(self, lato):
        self._lato = lato # Questo è un attributo protetto

    def descrivi(self):
        return f"Il lato del poligono è {self._lato}"

In questa classe la presenza del trattino nell'attributo "_lato" indica che si tratta di un attributo privato.

Ora crea un'istanza dalla classe "Poligono".

esagono = Poligono(6)

Per accedere al contenuto dell'attributo privato "_lato" devi usare il metodo descrivi()

print(esagono.descrivi())

6

Non puoi accedere all'attributo "lato" perché non esiste nella classe, in realtà l'attributo si chiama "_lato".

print(esagono.lato)

AttributeError: 'Poligono' object has no attribute 'lato'. Did you mean: '_lato'?

Tuttavia, nulla ti impedisce di accedere dall'esterno all'attributo "_lato" anche se è privato, se aggiungi un trattino in basso prima del nome.

print(esagono._lato)

6

Questo dimostra che in Python l'attributo è privato ma solo per convenzione, perché l'acccesso è tecnicamente possibile.

E' probabilmente meno immediato ma comunque possibile.

Doppio underscore (name mangling)

Il doppio underscore prima di un nome di attributo, come `__variabile`, fa sì che Python rinomina l'attributo per incorporare il nome della classe

Si tratta di un processo noto come "name mangling".

Come funziona? Il meccanismo di name mangling scatta quando inserisci due underscore (`__`) come prefisso del nome di un attributo. Il name mangling modifica internamente il nome dell'attributo aggiungendo il nome della classe.  Ad esempio, considera un attributo privato come:

`__attributo`

Se l'attributo si trova in una classe chiamata `Classe`, il name mangling lo rinomina internamente in:

`_Classe__attributo`

Il name mangling è pensato per ridurre la probabilità di sovrascrittura accidentale dell'attributo in sottoclassi che potrebbero avere lo stesso nome di attributo.

Il name mangling rende più difficile accedere all'attributo privato dall'esterno della classe.

Ad esempio, definisci questa classe:

class Poligono:
    def __init__(self, lato):
        self.__lato = lato # Questo è un attributo protetto

    def descrivi(self):
        return f"Il lato del poligono è {self.__lato}"

Nota che in questo caso l'attributo "__lato" ha due trattini in basso _ (underscore) all'inizio anziché uno.

Ora crea un'istanza della classe.

esagono = Poligono(6)

Puoi accedere al contenuto dell'attributo privato "__modello" usando il metodo descrivi() 

print(esagono.descrivi())

6

Non puoi però accedere direttamente all'attributo dall'esterno, perché verrebbe sollevato un AttributeError 

Questo si verifica perché l'attributo non si chiama più "__lato" poiché è stato modificato dal name mangling.

print(esagono.__lato)

AttributeError: 'Poligono' object has no attribute '__lato'

Tuttavia, non pensare però che sia impossibile accedere all'attributo privato. L'accesso agli attributi con due underscore non è bloccato completamente.

Nonostante questa trasformazione, puoi ancora accedere all'attributo "privato" se conosci il nome modificato dell'attributo all'interno della classe.

print(esagono._Poligono__lato)

6

Quindi, anche con i due underscore, l'attributo privato è ancora accessibile dall'esterno della classe, ma il processo è meno intuitivo e scoraggia l'accesso casuale o non autorizzato.

Perché usare gli attributi privati? L'uso di attributi privati ti aiuta a prevenire le modifiche accidentali dei dati e a mantenere l'integrità degli oggetti. Inoltre, rende più facile la manutenzione del codice, poiché i dettagli di implementazione interna sono nascosti e sono protetti dall'accesso diretto.

In sintesi, in Python la "privacy" degli attributi è più una questione di convenzione e buona pratica di programmazione che non una restrizione vera e propria.

Questo approccio promuove un modello di fiducia tra i programmatori, tipico dello spirito di Python, piuttosto che imporre dei limiti rigidi.




Se qualcosa non ti è chiaro, scrivi la tua domanda nei commenti.




FacebookTwitterLinkedinLinkedin