Python Academy · Pelajaran

TypeVar, Kelas Generik dan Protocol

Takrifkan jenis generik boleh guna semula dan subpenaipan struktur dengan Protocol.

Pelajaran 3 daripada 413 langkah

TypeVar, Kelas Generik dan Protocol ialah pelajaran Python Academy percuma di CoddyKit. Ini ialah pelajaran 3 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Python Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Python Academy merangkumi sejumlah 4 pelajaran.

Apakah TypeVar

TypeVar mengisytiharkan pemboleh ubah jenis — ruang letak yang boleh menerima apa-apa jenis, dengan kekangan jika perlu. Ia digunakan dalam fungsi dan kelas generik.

from typing import TypeVar

T = TypeVar("T")

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

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

Fungsi Generik

Fungsi yang menggunakan TypeVar dalam jenis parameter dan pulangan membolehkan mypy membuat inferens jenis pulangan daripada jenis argumen.

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

TypeVar Berkekangan

Hantar kekangan jenis kepada TypeVar untuk mengehadkan jenis yang boleh diterima.

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

Kelas Generik

Warisi daripada Generic[T] untuk mencipta kelas yang diparameterkan oleh pemboleh ubah jenis.

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

Pelbagai TypeVar

Gunakan beberapa TypeVar untuk memparameterkan kelas atau fungsi dengan dua jenis yang tidak saling bergantung.

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 — Subpenaipan Struktur

Protocol mentakrifkan antara muka melalui kaedah dan atribut yang mesti dimiliki oleh sesebuah kelas, tanpa memerlukan pewarisan eksplisit, iaitu penaipan itik yang diperiksa jenis.

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 dengan runtime_checkable

Tambahkan @runtime_checkable pada Protocol untuk mendayakan pemeriksaan isinstance() pada masa jalan.

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 berbanding ABC

ABC memerlukan pewarisan eksplisit (class Dog(Animal)). Protocol berfungsi melalui padanan struktur — jika sesebuah kelas mempunyai kaedah yang betul, kelas itu memenuhi protokol tanpa mengira pewarisan.

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

TypeVar("T", bound=BaseClass) mengehadkan T kepada BaseClass atau mana-mana subkelasnya.

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 Generik — Python 3.12

Python 3.12 memperkenalkan pernyataan type untuk alias jenis yang kemas dan sintaks class Foo[T] untuk generik tanpa mengimport 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()

Jenis Self

Self daripada typing dalam 3.11+ menganotasikan kaedah yang memulangkan kelas semasa, dan berguna dalam antara muka lancar serta subkelas.

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

Semakan Pantas

Apakah perbezaan utama antara Protocol dengan ABC dalam penaipan Python?

Rumusan

TypeVar mencipta ruang letak jenis untuk fungsi dan kelas generik. Generic[T] memparameterkan kelas. Protocol mendayakan subpenaipan struktur tanpa pewarisan. Gunakan bound= atau kekangan jenis pada TypeVar untuk mengehadkan jenis yang boleh diterima.

Percuma untuk bermula

Pelajari Python dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
76
Pelajaran
320

Soalan Lazim

Adakah pelajaran “TypeVar, Kelas Generik dan Protocol” percuma?

Ya — teks penuh “TypeVar, Kelas Generik dan Protocol” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Python Academy, tingkat taraf kepada CoddyKit PRO. Kursus Python Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “TypeVar, Kelas Generik dan Protocol”?

Takrifkan jenis generik boleh guna semula dan subpenaipan struktur dengan Protocol. Anda berlatih Python Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Python Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Python Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 3 daripada 4.

Berapa lamakah pelajaran “TypeVar, Kelas Generik dan Protocol” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Python Academy ini?

Ya. Setiap pelajaran Python Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Anotasi Jenis Asas
  2. Jenis Kompleks: List, Dict, Optional, Union
  3. TypeVar, Kelas Generik dan Protocol
  4. Menjalankan mypy dan Membetulkan Ralat Jenis
← Kembali ke Python Academy