TypeVar, classi generiche e Protocol
Definisca tipi generici riutilizzabili e il sottotipaggio strutturale con Protocol.
TypeVar, classi generiche e Protocol è una lezione Python Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Python Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Python Academy include 4 lezioni in totale.
Cos'è TypeVar?
TypeVar dichiara una variabile di tipo, ovvero un segnaposto che può rappresentare qualsiasi tipo, eventualmente con dei vincoli. Viene utilizzato nelle funzioni e nelle classi generiche.
from typing import TypeVar
T = TypeVar("T")
def identity(value: T) -> T:
return value
print(identity(42)) # int
print(identity("hello")) # strFunzioni generiche
Una funzione che utilizza TypeVar sia per i tipi dei parametri sia per il tipo restituito consente a mypy di dedurre il tipo restituito a partire dal tipo dell'argomento.
from typing import TypeVar
T = TypeVar("T")
def first(items: list[T]) -> T:
return items[0]
x: int = first([1, 2, 3]) # mypy knows x is int
s: str = first(["a","b","c"]) # mypy knows s is strTypeVar con vincoli
Passi dei vincoli di tipo a TypeVar per limitare i tipi accettabili.
from typing import TypeVar
Numeric = TypeVar("Numeric", int, float)
def double(n: Numeric) -> Numeric:
return n * 2
print(double(5)) # 10
print(double(2.5)) # 5.0
# double("x") # mypy errorClassi generiche
Erediti da Generic[T] per creare una classe parametrizzata da una variabile di tipo.
from typing import Generic, TypeVar
T = TypeVar("T")
class Stack(Generic[T]):
def __init__(self) -> None:
self._items: list[T] = []
def push(self, item: T) -> None:
self._items.append(item)
def pop(self) -> T:
return self._items.pop()
stack: Stack[int] = Stack()
stack.push(1)
print(stack.pop()) # 1Più TypeVar
Utilizzi più TypeVar per parametrizzare una classe o una funzione con due tipi indipendenti.
from typing import Generic, TypeVar
K = TypeVar("K")
V = TypeVar("V")
class Pair(Generic[K, V]):
def __init__(self, key: K, value: V) -> None:
self.key = key
self.value = value
p: Pair[str, int] = Pair("age", 30)
print(p.key, p.value) # age 30Protocol — Sottotipizzazione strutturale
Protocol definisce un'interfaccia in base ai metodi e agli attributi che una classe deve avere, senza richiedere un'ereditarietà esplicita ("duck typing, con controllo dei tipi").
from typing import Protocol
class Drawable(Protocol):
def draw(self) -> None: ...
def render(obj: Drawable) -> None:
obj.draw()
class Circle:
def draw(self) -> None:
print("Drawing circle")
render(Circle()) # works — Circle satisfies DrawableProtocol con runtime_checkable
Aggiunga @runtime_checkable a un Protocol per abilitare i controlli isinstance() a runtime.
from typing import Protocol, runtime_checkable
@runtime_checkable
class Closeable(Protocol):
def close(self) -> None: ...
class File:
def close(self) -> None: print("closed")
print(isinstance(File(), Closeable)) # TrueProtocol e ABC a confronto
Le ABC richiedono un'ereditarietà esplicita (class Dog(Animal)). I Protocol funzionano tramite corrispondenza strutturale: se una classe dispone dei metodi corretti, soddisfa il protocollo indipendentemente dall'ereditarietà.
from typing import Protocol
from abc import ABC, abstractmethod
# ABC: nominal typing
class Printable(ABC):
@abstractmethod
def display(self) -> None: ...
# Protocol: structural typing
class Displayable(Protocol):
def display(self) -> None: ...TypeVar con bound
TypeVar("T", bound=BaseClass) limita T a BaseClass o a una qualsiasi delle sue sottoclassi.
from typing import TypeVar
class Animal:
def speak(self) -> str: return "..."
A = TypeVar("A", bound=Animal)
def make_speak(animal: A) -> str:
return animal.speak()Alias generici — Python 3.12
Python 3.12 introduce l'istruzione type per creare alias di tipo chiari e la sintassi class Foo[T] per i generici senza importare TypeVar.
# Python 3.12+
type Vector = list[float]
type Matrix = list[Vector]
class Stack[T]:
def __init__(self) -> None: self._items: list[T] = []
def push(self, item: T) -> None: self._items.append(item)
def pop(self) -> T: return self._items.pop()Tipo Self
Self (da typing in 3.11+) annota i metodi che restituiscono la classe corrente, risultando utile nelle interfacce fluent e nelle sottoclassi.
from typing import Self
class Builder:
def __init__(self) -> None:
self.parts: list[str] = []
def add(self, part: str) -> Self:
self.parts.append(part)
return self
b = Builder().add("a").add("b")
print(b.parts) # ["a", "b"]Verifica rapida
Qual è la differenza fondamentale tra un Protocol e una ABC nel sistema di tipizzazione di Python?
Riepilogo
TypeVar crea segnaposto di tipo per funzioni e classi generiche. Generic[T] parametrizza le classi. Protocol abilita la sottotipizzazione strutturale senza ereditarietà. Utilizzi bound= o i vincoli di tipo su TypeVar per limitare i tipi accettabili.
Domande Frequenti
La lezione «TypeVar, classi generiche e Protocol» è gratuita?
Sì — il testo completo di «TypeVar, classi generiche e Protocol» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Python Academy, passa a CoddyKit PRO. Il corso Python Academy include 4 lezioni in totale.
Cosa imparerò in «TypeVar, classi generiche e Protocol»?
Definisca tipi generici riutilizzabili e il sottotipaggio strutturale con Protocol. Eserciti Python Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Python Academy?
Non è richiesta alcuna esperienza precedente. Python Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.
Quanto tempo richiede la lezione «TypeVar, classi generiche e Protocol»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Python Academy?
Sì. Ogni lezione Python Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Annotazioni di tipo di base
- Tipi complessi: List, Dict, Optional, Union
- TypeVar, classi generiche e Protocol
- Esecuzione di mypy e correzione degli errori di tipo