# La funzione property in Python: come chiamare i metodi getter e setter in modo implicito

La funzione property in Python permette di assegnare facilmente valori agli attributi da una classe Python. I relativi metodi getter o setter vengono chiamati automaticamente.

## Cos’è esattamente la funzione property in Python e a cosa serve?

In Python, le proprietà sono un costrutto di programmazione che gli sviluppatori e le sviluppatrici possono usare nella **programmazione orientata agli oggetti**, definendo metodi ai quali poi accedere come agli attributi. Permettono un **accesso più intuitivo agli attributi di una classe**, rendendo tra l’altro superfluo chiamare metodi setter e getter dedicati. Le proprietà in Python trasformano gli attributi delle classi in proprietà chiamate “**attributi gestiti**”.

Inoltre, una proprietà in Python realizza una sorta di controllo degli accessi: permette di assicurare che altri metodi non accedano facilmente ai dati dell’attributo e non possano modificarli in modo indesiderato.

Consiglio Se utilizzate Python per realizzare un progetto web, vale la pena di dare uno sguardo anche a [Deploy Now](https://www.ionos.it/hosting/deploy-now "Deploy Now di IONOS"). Questo pratico strumento vi permette di compilare e distribuire il vostro codice direttamente tramite GitHub, aumentando enormemente l’efficienza del flusso di lavoro.

## La funzione property() in Python

Per utilizzare le proprietà, gli sviluppatori e le sviluppatrici possono servirsi della funzione property() in Python. Si tratta di una **funzione integrata** utilizzabile senza dover importare ulteriori moduli. La funzione property() stessa è implementata nel linguaggio di programmazione C, garantendo prestazioni ottimali.

La sintassi della funzione property() in Python si presenta come segue:

```Python
property(fget=None, fset=None, fdel=None, doc=None)
```

I parametri della funzione property() sono opzionali. Nella tabella seguente potete scoprire il significato dei singoli parametri:

<table>
  <thead>
    <tr>
      <th><strong>Parametro</strong></th>
      <th><strong>Significato</strong></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>fget</td>
      <td>Funzione che restituisce il valore dell’attributo (metodo getter)</td>
    </tr>
    <tr>
      <td>fset</td>
      <td>Funzione che permette di impostare il valore dell’attributo (metodo setter)</td>
    </tr>
    <tr>
      <td>fdel</td>
      <td>Funzione che indica come deve essere eliminato l’attributo</td>
    </tr>
    <tr>
      <td>doc</td>
      <td>[Stringa Python](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/stringhe-in-python/ "Stringhe in Python") che descrive la proprietà</td>
    </tr>
  </tbody>
</table>

## Il decoratore property in Python

Non è strettamente necessario utilizzare la funzione property() per lavorare con le proprietà. Spesso si ricorre a un [decoratore Python](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/decoratori-python/) predefinito che permette di utilizzare un metodo della classe come property. Il linguaggio di programmazione supporta **tre decoratori diversi** con la famosa notazione @ per permettervi di definire una proprietà:

- @property: definisce un metodo della vostra classe come property Python
- @property-name.setter: specifica un metodo setter che imposta il valore di una proprietà
- @property-name.deleter: specifica il metodo che elimina una proprietà.

N.B. Se siete interessati o interessate a [tutorial di Python](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/tutorial-python/ "Tutorial di Python") avanzati, vi consigliamo di consultare gli articoli seguenti:

- [Iteratori Python](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/iteratori-python/)
- [Generatori Python](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/generatori-python/)
- [RegEx in Python](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/regex-in-python/)

## Esempio di property in Python

Per illustrare il funzionamento e l’utilità della funzione property in Python ricorriamo a un esempio di codice. Nella sezione di codice che segue, per prima cosa si crea una classe chiamata “cane” con l’attributo “\_name”. Nonostante questo esempio sia effettivamente piuttosto artificiale e non abbia una reale utilità, è perfetto per mostrare il **funzionamento delle proprietà in Python.**

```Python
class cane:
	def __init__(self):
		self._name = "Fido"
```

Come potete vedere, al costruttore non viene passato nessun parametro che specifica il nome del nostro cane. L’impostazione predefinita è “Fido”. Potete dunque creare un oggetto della classe, ad esempio con la riga di codice seguente:

```Python
cane = cane()
```

### Metodi getter e setter

Potete ampliare la vostra classe con metodi getter e setter specifici. È utile farlo per diversi motivi, ma qui sottolineiamo soprattutto la **facilità di manutenzione** del codice e l’**integrazione di funzionalità aggiuntive**. Siccome per impostazione predefinita i nomi sono stringhe, nella nostra classe vogliamo anche assicurarci che sia effettivamente passato un nome sotto forma di stringa. A questo scopo scriviamo la relativa logica di funzionamento in un metodo setter dedicato e ampliamo la definizione della classe sopra:

```Python
class cane:
	def __init__(self):
		self._name = "Fido"
	
	def getName(self):
		return self._name
	def setName(self, name):
		if isinstance(name, str):
			self._name = name
		else:
			return
```

Nel metodo setter chiamato “setName”, con un’[istruzione if-else in Python](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/if-else-in-python/ "if-else in Python") si verifica se il parametro passato è una stringa. Se lo è, viene impostato il nome, altrimenti non succede nulla.

Abbiamo inoltre specificato un metodo getter che restituisce il nome del cane.

Possiamo creare un oggetto della nostra classe con il nome “Lassie” come segue:

```Python
lassie = cane()
lassie.setName("Lassie")
print(lassie.getName())
```

L’output si presenta come segue, quindi come desiderato:

```none
'Lassie'
```

N.B. A differenza di altri linguaggi di programmazione, Python **non prevede la possibilità** di differenziare tra gli attributi di classe che possono essere usati dall’esterno direttamente, senza metodi getter o setter (in altri linguaggi questi attributi sono spesso definiti “public”), e quelli che non possono essere modificati facilmente dall’esterno (in altri linguaggi “private”). Pertanto, convenzionalmente gli attributi dei nomi delle variabili che non devono essere usati senza metodi getter e setter **iniziano con un carattere di sottolineatura.**

### La funzione property() in Python

Per evitare di chiamare esplicitamente una funzione allo scopo di modificare o scoprire il nome del cane in Python, ci serviamo ora della funzione property. A fini dimostrativi inseriamo anche un’istruzione print nel nostro metodo getter e setter.

```Python
class cane:
	def __init__(self):
		self._name = "Fido"
	def getName(self):
		print("metodo getter chiamato")
		return self._name
	def setName(self, name):
		if isinstance(name, str):
			self._name = name
			print("metodo setter chiamato")
		else:
			return
	
	name = property(getName, setName)
```

Come potete vedere, per chiamare la funzione property() non abbiamo dovuto fare nient’altro che **creare un nuovo attributo chiamato “name”** (questa volta non preceduto dal carattere di sottolineatura, perché grazie alla property Python la funzione può essere chiamata facilmente dall’esterno) e assegnare a esso il risultato della chiamata di funzione. Come parametro, la funzione property() riceve i già noti metodi getter e setter.

A questo punto, creando un ulteriore oggetto della classe con il nome “Snoopy”, vedete subito la differenza:

```Python
snoopy = cane()
snoopy.name = "Snoopy"
snoopy.name
```

Ora si può accedere facilmente agli attributi della classe con la notazione con punto. È interessante in particolare l’output del programma:

```none
Metodo setter chiamato
Metodo getter chiamato
'Snoopy'
```

Anche se **non sono stati chiamati esplicitamente**, i metodi getter e setter sono stati eseguiti al momento dell’assegnazione o dell’interrogazione del nome dell’oggetto “Snoopy” mediante la notazione con punto. Questo grazie alla funzione property in Python.

### Il decoratore property in Python

Potete ottenere lo stesso effetto con i già menzionati decoratori di funzioni. In questo caso, il codice di esempio si presenta come segue (attenzione: ora i due metodi decorati devono avere lo stesso nome):

```Python
class cane:
	def __init__(self):
		self._name = "Fido"
	@property
	def name(self):
		print("metodo setter chiamato")
		return self._name
	@name.setter
	def name(self, name):
		if isinstance(name, str):
			self._name = name
			print("metodo getter chiamato")
		else:
			return
```

Di nuovo, potete creare un oggetto della vostra classe e impostare e selezionare l’attributo “name” mediante la notazione con punto.

```Python
tintin = cane()
tintin.name = "Tintin"
tintin.name
```

Rispetto a quando abbiamo usato la funzione property() in Python, l’output non è cambiato:

```none
Metodo setter chiamato
Metodo getter chiamato
'Tintin'
```


This is a markdown version of: [https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/property-in-python/](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/property-in-python/) for AI/LLM consumption.