Python Academy · leksjon

TypeVar, generiske klasser og Protocol

Definer gjenbrukbare generiske typer og strukturell subtyping med Protocol.

Leksjon 3 av 413 trinn

TypeVar, generiske klasser og Protocol er en gratis leksjon i Python Academy på CoddyKit. Dette er leksjon 3 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Python Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Python Academy inneholder totalt 4 leksjoner.

Hva er TypeVar

TypeVar deklarerer en typevariabel – en plassholder som kan ha en hvilken som helst type, eventuelt med begrensninger. Den brukes i generiske funksjoner og klasser.

from typing import TypeVar

T = TypeVar("T")

def identity(value: T) -> T:
    return value

print(identity(42))      # int
print(identity("hello")) # str

Generiske funksjoner

En funksjon som bruker TypeVar både i parameter- og returtypene, lar mypy utlede returtypen fra argumenttypen.

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 str

Begrenset TypeVar

Send typebegrensninger til TypeVar for å begrense hvilke typer som kan godtas.

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 error

Generiske klasser

Arv fra Generic[T] for å opprette en klasse som er parameterisert med en typevariabel.

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())   # 1

Flere TypeVar-variabler

Bruk flere TypeVar-variabler for å parameterisere en klasse eller funksjon med to uavhengige typer.

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 30

Protocol – strukturell subtyping

Protocol definerer et grensesnitt gjennom metodene og attributtene en klasse må ha, uten krav om eksplisitt arv («duck typing, type-checked»).

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 Drawable

Protocol med runtime_checkable

Legg @runtime_checkable til en Protocol for å aktivere isinstance()-kontroller ved kjøring.

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))   # True

Protocol kontra ABC

ABC-er krever eksplisitt arv (class Dog(Animal)). Protocol-er fungerer gjennom strukturell samsvarskontroll – hvis en klasse har de riktige metodene, oppfyller den protokollen uavhengig av arv.

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 med bound

TypeVar("T", bound=BaseClass) begrenser T til BaseClass eller en av underklassene.

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()

Generisk alias – Python 3.12

Python 3.12 introduserer type-setningen for ryddige typealiaser og class Foo[T]-syntaks for generiske typer uten import av 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()

Self-typen

Self (fra typing i 3.11+) annoterer metoder som returnerer den gjeldende klassen, noe som er nyttig i flytende grensesnitt og underklasser.

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"]

Kort kontroll

Hva er den viktigste forskjellen mellom en Protocol og en ABC i Pythons typesystem?

Oppsummering

TypeVar oppretter typeplassholdere for generiske funksjoner og klasser. Generic[T] parameteriserer klasser. Protocol muliggjør strukturell subtyping uten arv. Bruk bound= eller typebegrensninger på TypeVar for å begrense hvilke typer som godtas.

Gratis å komme i gang

Lær deg Python med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
76
Leksjoner
320

Ofte stilte spørsmål

Er leksjonen «TypeVar, generiske klasser og Protocol» gratis?

Ja – hele teksten i «TypeVar, generiske klasser og Protocol» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Python Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Python Academy inneholder totalt 4 leksjoner.

Hva lærer jeg i «TypeVar, generiske klasser og Protocol»?

Definer gjenbrukbare generiske typer og strukturell subtyping med Protocol. Du øver på Python Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Python Academy?

Ingen tidligere erfaring er nødvendig. Python Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.

Hvor lang tid tar leksjonen «TypeVar, generiske klasser og Protocol»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Python Academy-leksjonen?

Ja. Alle Python Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Grunnleggende typeannotasjoner
  2. Komplekse typer: List, Dict, Optional, Union
  3. TypeVar, generiske klasser og Protocol
  4. Kjøre mypy og rette typefeil
← Tilbake til Python Academy