0Pricing
Python Academy · บทเรียน

TypeVar คลาสทั่วไป และ Protocol

กำหนดชนิดข้อมูลทั่วไปที่ใช้ซ้ำได้และการสืบทอดชนิดเชิงโครงสร้างด้วย Protocol

TypeVar คลาสทั่วไป และ Protocol เป็นบทเรียน Python Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Python Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน

TypeVar คืออะไร

TypeVar ใช้ประกาศตัวแปรชนิดข้อมูล ซึ่งเป็นตัวแทนที่สามารถแทนชนิดข้อมูลใดก็ได้ และสามารถจำกัดชนิดข้อมูลได้ตามต้องการ ใช้ในฟังก์ชันและคลาสแบบทั่วไป

from typing import TypeVar

T = TypeVar("T")

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

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

ฟังก์ชันแบบเจเนอริก

ฟังก์ชันที่ใช้ TypeVar ทั้งในชนิดของพารามิเตอร์และชนิดของค่าที่ส่งกลับ ช่วยให้ mypy อนุมานชนิดของค่าที่ส่งกลับจากชนิดของอาร์กิวเมนต์ได้

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 แบบมีข้อจำกัด

ส่งข้อจำกัดของชนิดข้อมูลให้กับ TypeVar เพื่อจำกัดชนิดข้อมูลที่ยอมรับได้

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

คลาสแบบเจเนอริก

สืบทอดจาก Generic[T] เพื่อสร้างคลาสที่กำหนดพารามิเตอร์ด้วยตัวแปรชนิดข้อมูล

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

TypeVar หลายตัว

ใช้ TypeVar หลายตัวเพื่อกำหนดพารามิเตอร์ให้คลาสหรือฟังก์ชันด้วยชนิดข้อมูลอิสระสองชนิด

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 — การสืบชนิดแบบโครงสร้าง

Protocol กำหนดอินเทอร์เฟซด้วยเมธอดและแอตทริบิวต์ที่คลาสต้องมี โดยไม่บังคับให้สืบทอดอย่างชัดเจน (การกำหนดชนิดแบบเป็ดที่มีการตรวจสอบชนิดข้อมูล)

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 พร้อม runtime_checkable

เพิ่ม @runtime_checkable ให้กับ Protocol เพื่อเปิดใช้การตรวจสอบ isinstance() ขณะทำงาน

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 กับ ABC

ABC ต้องสืบทอดอย่างชัดเจน (class Dog(Animal)) ส่วน Protocol ทำงานด้วยการจับคู่ตามโครงสร้าง หากคลาสมีเมธอดที่ถูกต้อง คลาสนั้นก็จะสอดคล้องกับโพรโทคอลโดยไม่ขึ้นกับการสืบทอด

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 พร้อม bound

TypeVar("T", bound=BaseClass) จำกัดให้ T เป็น BaseClass หรือคลาสลูกใด ๆ ของ BaseClass

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

นามแฝงแบบเจเนอริก — Python 3.12

Python 3.12 เพิ่มคำสั่ง type สำหรับสร้างนามแฝงชนิดข้อมูลที่อ่านง่าย และไวยากรณ์ class Foo[T] สำหรับชนิดข้อมูลแบบทั่วไป โดยไม่ต้องนำเข้า 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

Self (จาก typing ใน 3.11 ขึ้นไป) ใช้อธิบายเมธอดที่ส่งคืนคลาสปัจจุบัน เหมาะสำหรับอินเทอร์เฟซแบบต่อเมธอดและคลาสลูก

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

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ความแตกต่างสำคัญระหว่าง Protocol กับ ABC ในระบบชนิดข้อมูลของ Python คืออะไร

สรุป

TypeVar สร้างตัวแทนชนิดข้อมูลสำหรับฟังก์ชันและคลาสแบบทั่วไป Generic[T] ใช้กำหนดพารามิเตอร์ให้คลาส Protocol เปิดใช้การสืบชนิดตามโครงสร้างโดยไม่ต้องสืบทอด ใช้ bound= หรือข้อจำกัดชนิดข้อมูลกับ TypeVar เพื่อจำกัดชนิดข้อมูลที่ยอมรับได้

คำถามที่พบบ่อย

บทเรียน “TypeVar คลาสทั่วไป และ Protocol” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “TypeVar คลาสทั่วไป และ Protocol” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Python Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “TypeVar คลาสทั่วไป และ Protocol”

กำหนดชนิดข้อมูลทั่วไปที่ใช้ซ้ำได้และการสืบทอดชนิดเชิงโครงสร้างด้วย Protocol คุณปฏิบัติ Python Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Python Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Python Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “TypeVar คลาสทั่วไป และ Protocol” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Python Academy นี้ได้ไหม

ได้ บทเรียน Python Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. คำอธิบายชนิดข้อมูลเบื้องต้น
  2. ชนิดข้อมูลซับซ้อน: List, Dict, Optional, Union
  3. TypeVar คลาสทั่วไป และ Protocol
  4. การเรียกใช้ mypy และแก้ข้อผิดพลาดด้านชนิดข้อมูล
← กลับไปที่ Python Academy