# Creare classi e oggetti in Python

Le classi di Python sono strutture che fungono da **modello o prototipo per la creazione di oggetti**. Possono essere utilizzate per scrivere codice riutilizzabile sotto forma di attributi e metodi.

## Cosa sono le classi di Python?

Una classe è un **concetto astratto** che definisce gli attributi e i metodi che un oggetto può avere. Le classi di Python servono come modello per la creazione di oggetti concreti che svolgono il ruolo di istanze di questa classe. Per fare un esempio concreto, una classe può chiamarsi `Automobile`, avere come attributi il colore e la casa produttrice e come metodi `__guidare__` e `__frenare__`.

Ogni oggetto di una classe può avere valori propri per quanto riguarda gli attributi, ma **condivide i metodi e il quadro comportamentale di base con altre istanze** della stessa classe. Ad esempio, possiamo creare l’oggetto `mia_auto` all’interno della classe `auto` e dargli come attributi il colore `__rosso__` e la casa produttrice `__Toyota__`. I metodi `__guidare__` e `__frenare__` della classe vengono automaticamente trasferiti all’istanza.

## Come creare classi in Python

In Python le classi si definiscono utilizzando la parola chiave `class`.

```python
lass MyClass:
    # Constructor method called when creating an object
    def __init__(self, attribute1, attribute2):
        self.attribute1 = attribute1
        self.attribute2 = attribute2
    
    # Method defined within the class
    def my_method(self):
        return f"Attribute 1: {self.attribute1}, Attribute 2: {self.attribute2}"
```

In questo codice Python, stiamo creando una classe chiamata `MyClass`. Questa ha un **costruttore** `__init__` che viene richiamato al momento della creazione di un oggetto e inizializza due attributi, `attribute1` e `attribute2`. Il metodo `my_method` restituisce una stringa formattata contenente i valori di questi attributi.

Per derivare un oggetto da questa classe, occorre utilizzare il nome della classe seguito da parentesi:

```python
object1 = MyClass("Value 1", "Value 2")
# Calling a method of the object
result = object1.my_method()
```

## Esempi di utilizzo delle classi in Python

Le classi di Python possono creare sistemi complessi e relazioni tra entità diverse. Di seguito ti presentiamo alcuni modi per lavorare con le classi in Python.

### La funzione `__str()__`

La funzione `__str__()` è un metodo speciale che può essere definito all’interno delle classi di Python. Quando viene implementata, restituisce una stringa che rappresenta una **rappresentazione user-friendly di un oggetto**. Puoi utilizzare la funzione `str()` direttamente sull’oggetto o combinarla con un’istruzione `print()`.

```python
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __str__(self):
        return f"Name: {self.name}, Age: {self.age}"
person1 = Person("Alice", 30)
print(person1) # Output: Name: Alice, Age: 30
```

Nel nostro codice, il metodo `__str__()` della classe `person` crea una **stringa formattata** contenente il nome e l’età di una persona. Eseguendo la funzione `print(person1)`, viene automaticamente richiamato il metodo `__str__()` dell’oggetto `person1` e viene generata la stringa restituita da questo metodo.

### Definire i metodi nelle classi di Python

In Python, hai la possibilità di **definire metodi all’interno di una classe** per eseguire operazioni sugli oggetti da essa contenuti. Questi metodi possono poi essere richiamati dagli oggetti creati.

```python
class Rectangle:
    def __init__(self, length, width):
        self.length = length
        self.width = width
    
    def area(self):
        return self.length * self.width
    def perimeter(self):
        return 2 * (self.length + self.width)
# Creating an object of the class
my_rectangle = Rectangle(5, 10)
# Calling methods of the object
area = my_rectangle.area()
perimeter = my_rectangle.perimeter()
# Printing the calculated values
print("Area =", area) # Output: Area = 50
print("Perimeter =", perimeter) # Output: Perimeter = 30
```

Nell’esempio, creiamo la classe `Rectangle`, che include i due metodi `area()` e `perimeter()`. Questi vengono utilizzati per calcolare l’area e il perimetro di un rettangolo in base ai valori di lunghezza e larghezza forniti al momento dell’inizializzazione dell’oggetto. Nel linguaggio Python, `self` all’interno di un metodo di una classe rappresenta un **riferimento all’oggetto corrente** a cui il metodo viene applicato.

Dopo aver creato l’oggetto `my_rectangle` con una lunghezza di 5 e una larghezza di 10, richiamiamo i metodi `area()` e `perimeter()` su questo oggetto per calcolare i valori corrispondenti.

### Modificare le proprietà degli oggetti

L’operatore punto `.` può essere utilizzato per accedere agli **attributi specifici dell’oggetto** e aggiornarne i valori. È possibile assegnare nuovi valori direttamente all’attributo.

```python
person1.name = "Sarah"
person1.age = 35
```

La parola chiave `del` consente di cancellare le proprietà di un oggetto.

```python
del person1.name
```

N.B. Ricorda che le variabili di istanza sono diverse dalle [variabili di classe in Python](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/python-class-variables/). Le variabili di classe sono **definite fuori dal costruttore** e possono essere modificate solo tramite il nome della classe.


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