Notes & software courses · Free to learn
Aph's Blog
On this page

Type Hints & mypy

👋 อ่านฟรีทั้งหมดบน Aph's Blog — เนื้อหาภาษาไทย ทำตามทีละหน้าใน sidebar ได้เลย หากมีข้อเสนอแนะหรืออยากให้เพิ่มหัวข้อไหน บอกได้เสมอ

บอกชนิดข้อมูลในโค้ดเพื่อให้ editor และเครื่องมือช่วยจับ bug ก่อนรัน — มาตรฐานทีมสมัยใหม่

Python ไม่บังคับประกาศชนิดข้อมูล แต่ type hint ให้เรา "เขียนบอก" ได้ว่าตัวแปร/พารามิเตอร์/ค่าคืนเป็นชนิดอะไร มันไม่บังคับตอนรัน แต่ช่วยให้ editor autocomplete แม่นและเครื่องมืออย่าง mypy จับ bug ได้ก่อนโปรแกรมรันจริง

type hint พื้นฐาน

python
def greet(name: str, times: int = 1) -> str:
    return (f"สวัสดี {name} ") * times

age: int = 25
price: float = 19.99
is_active: bool = True

# hint ไม่บังคับตอนรัน — ใส่ผิดชนิดก็ยังรันได้
# แต่ mypy/editor จะเตือน

อ่านว่า: name เป็น str, times เป็น int (default 1), ฟังก์ชันคืน str (-> str)

ชนิดของ collection

python
# Python 3.9+ ใช้ตัวพิมพ์เล็กได้เลย
names: list[str] = ["Aph", "Bee"]
scores: dict[str, int] = {"Aph": 90}
coords: tuple[int, int] = (3, 4)

def average(nums: list[float]) -> float:
    return sum(nums) / len(nums)

ค่าที่อาจเป็น None (Optional)

ถ้าค่าอาจเป็นชนิดหนึ่งหรือ None ใช้ X | None (สมัยใหม่) หรือ Optional[X] — บอกชัดว่าต้องเช็ค None ก่อนใช้

python
def find_user(user_id: int) -> str | None:
    users = {1: "Aph", 2: "Bee"}
    return users.get(user_id)    # คืน str หรือ None

name = find_user(99)
if name is not None:             # ต้องเช็คก่อนใช้
    print(name.upper())

dataclass — class สำหรับเก็บข้อมูล

ถ้าต้องการ class ที่มีแต่ข้อมูล @dataclass สร้าง __init__, __repr__, การเปรียบเทียบให้อัตโนมัติ พร้อมใช้ type hint เต็ม — สั้นและชัด

python
from dataclasses import dataclass

@dataclass
class Point:
    x: int
    y: int

p = Point(3, 4)
print(p)            # Point(x=3, y=4)  (__repr__ ให้ฟรี)
print(p.x + p.y)    # 7
print(p == Point(3, 4))   # True  (เทียบค่าให้ฟรี)

ตรวจด้วย mypy

mypy คือเครื่องมือที่อ่าน type hint แล้วเตือน bug เรื่องชนิดก่อนรันโปรแกรม

bash
pip install mypy
mypy myfile.py
# error: Argument 1 to "greet" has incompatible type "int"; expected "str"
type hint คุ้มค่าตรงไหน

ในโปรเจกต์เล็กอาจไม่เห็นผลชัด แต่พอโค้ดใหญ่/ทำงานเป็นทีม type hint ช่วยมหาศาล: autocomplete แม่นขึ้น, จับ bug ก่อนรัน, และเป็นเอกสารในตัว FastAPI (บท Web) ใช้ type hint สร้าง validation + docs อัตโนมัติด้วย

สรุปหัวข้อนี้

  • type hint บอกชนิด: name: str, -> int — ไม่บังคับตอนรันแต่ช่วยมาก
  • collection: list[str], dict[str, int], tuple[int, int]
  • ค่าที่อาจเป็น None: X | None แล้วต้องเช็คก่อนใช้
  • @dataclass สร้าง __init__/__repr__/เทียบค่าให้; mypy ตรวจชนิดก่อนรัน
แบบฝึกหัด

1) ใส่ type hint เต็มให้ฟังก์ชัน average(nums) -> float 2) เขียนฟังก์ชันที่คืน str | None แล้วเช็ค None ก่อนใช้ 3) แปลง class ที่มีแต่ข้อมูลให้เป็น @dataclass 4) ติดตั้ง mypy แล้วลองรันกับไฟล์ที่จงใจใส่ชนิดผิด