Skip to content

บทที่ 5.4: Type Hinting (การระบุและตรวจสอบ Static Type Annotation)

เอกสารนี้อธิบายเกี่ยวกับการใช้งาน Type Hinting ในภาษา Python เพื่อระบุชนิดข้อมูลของตัวแปร พารามิเตอร์ และค่าคืนกลับของฟังก์ชัน ซึ่งช่วยเพิ่ม readability ของโค้ด ลดข้อผิดพลาด และเพิ่มประสิทธิภาพในการทำงานร่วมกับ IDE และ Static Type Checkers


1. พื้นฐาน Type Hinting (Basic Annotations)

แม้ว่า Python จะเป็นภาษา Dynamic Typing แต่เราสามารถระบุ Type Hint เพื่อบอกชนิดข้อมูลที่คาดหวังได้ โดยไม่ส่งผลต่อการประมวลผลจริงในขณะ Runtime

# การระบุชนิดข้อมูลให้กับตัวแปร
age: int = 25
name: str = "Sebastian"
is_active: bool = True
price: float = 199.99

# การระบุชนิดข้อมูลให้พารามิเตอร์และ Return Value ของฟังก์ชัน
def calculate_discount(price: float, discount_percentage: float) -> float:
    return price * (1 - discount_percentage / 100)

result: float = calculate_discount(1000.0, 10.0)
print(result)  # Output: 900.0

2. การใช้ Type Hinting กับ Collections

ใน Python เวอร์ชันปัจจุบัน (3.9+) สามารถใช้ Built-in Types ในการกำหนด Type ของข้อมูลภายใน List, Dictionary, Tuple หรือ Set ได้โดยตรง

# List ของข้อมูลชนิด int
numbers: list[int] = [1, 2, 3, 4, 5]

# Dictionary ที่มี Key เป็น str และ Value เป็น int
scores: dict[str, int] = {"Alice": 90, "Bob": 85}

# Tuple ที่มีโครงสร้างแน่นอน (ตำแหน่งที่ 0 เป็น str, ตำแหน่งที่ 1 เป็น int)
user_info: tuple[str, int] = ("John", 30)

# Set ของข้อมูลชนิด str
unique_tags: set[str] = {"python", "coding", "backend"}

3. ชนิดข้อมูลระดับสูงจากโมดูล typing (Advanced Types)

กรณีต้องการระบุความยืดหยุ่นของชนิดข้อมูล สามารถใช้งานโมดูล typing หรือ Syntax ตัวดำเนินการ | (ใน Python 3.10+) ได้

3.1 Union / Optional (| Operator)

ใช้เมื่อข้อมูลรองรับได้หลายชนิด หรือยอมรับค่า None ได้

# Python 3.10+ (แนะนำ): ใช้ตัวดำเนินการ |
def process_id(user_id: int | str) -> str:
    return f"ID: {user_id}"

# ค่าคืนกลับอาจเป็น str หรือ None (Optional)
def find_user(user_id: int) -> str | None:
    if user_id == 1:
        return "Alice"
    return None

3.2 Callable และ Any

  • Callable: ใช้ระบุ Type ของฟังก์ชันที่เป็น พารามิเตอร์
  • Any: ใช้เมื่อต้องการข้ามการตรวจสอบ Type (ไม่จำกัดชนิดข้อมูล)
from typing import Callable, Any

# พารามิเตอร์ op เป็นฟังก์ชันที่รับ int สองตัวแล้วคืนค่าเป็น int
def execute_operation(a: int, b: int, op: Callable[[int, int], int]) -> int:
    return op(a, b)

def add(x: int, y: int) -> int:
    return x + y

print(execute_operation(5, 3, add))  # Output: 8

# ข้อมูลชนิดใดก็ได้
data: Any = "Hello"
data = 123  # ไม่เกิด warning

4. การใช้ Custom Class เป็น Type Hint

เราสามารถนำ Class ที่สร้างขึ้นเองมาใช้เป็น Type Hint ได้ทันที

class User:
    def __init__(self, name: str, email: str):
        self.name = name
        self.email = email

def send_welcome_email(user: User) -> bool:
    print(f"ส่งอีเมลต้อนรับไปยัง {user.email}")
    return True

user_obj = User("Alex", "alex@example.com")
send_welcome_email(user_obj)

5. การตรวจสอบ Type ด้วย Static Analysis Tools

เนื่องจาก Python ไม่ได้บังคับ Type ในระดับ Runtime โค้ดที่มีการระบุ Type ผิดจะยังสามารถทำงานได้หากไวยากรณ์ถูกต้อง ดังนั้น โปรแกรมเมอร์จึงนิยมใช้เครื่องมือภายนอก เช่น mypy ในการตรวจสอบ Type ล่วงหน้า

# ติดตั้ง mypy
pip install mypy

# สั่งตรวจสอบไฟล์
mypy script.py