คู่มือ Type Hint Python: อ่านง่ายและดูแลง่าย

  • เพิ่มความสามารถในการอ่าน: ด้วย type hints ทำให้ชนิดของตัวแปรและฟังก์ชันถูกระบุอย่างชัดเจน จึงช่วยให้นักพัฒนาคนอื่นเข้าใจโค้ดได้ง่ายขึ้น
  • การตรวจพบบั๊กตั้งแต่เนิ่นๆ: โดยใช้เครื่องมืออย่าง mypy คุณสามารถตรวจจับความไม่ตรงกันของชนิดข้อมูลได้ก่อนการรันโค้ด
  • เพิ่มประสิทธิภาพในการพัฒนา: เมื่อทำงานร่วมกับฟังก์ชันการเติมคำอัตโนมัติของเอดิเตอร์ จะช่วยให้การเขียนโค้ดดำเนินไปอย่างราบรื่นยิ่งขึ้น
目次

2. วิธีเขียน Type Hint ขั้นพื้นฐาน

Type Hint เป็นฟีเจอร์ที่ถูกเพิ่มอย่างเป็นทางการตั้งแต่ Python 3.5 ทำให้สามารถระบุชนิดข้อมูลในโค้ดได้อย่างชัดเจน ซึ่งช่วยให้นักพัฒนาทำความเข้าใจพฤติกรรมของโค้ดได้ชัดเจนยิ่งขึ้น

วิธีใส่ Type Hint ให้กับตัวแปร

การใส่ Type Hint ให้ตัวแปรทำได้ไม่ยาก เพียงระบุชนิดข้อมูลต่อท้ายชื่อตัวแปรดังตัวอย่างต่อไปนี้
x: int = 10
y: float = 3.14
name: str = "John"

Type Hint สำหรับอาร์กิวเมนต์และค่าที่คืนกลับของฟังก์ชัน

ในฟังก์ชัน เราสามารถใส่ Type Hint ให้กับอาร์กิวเมนต์และค่าที่คืนกลับได้เช่นกัน ตัวอย่างเช่น ฟังก์ชันด้านล่างระบุไว้อย่างชัดเจนว่าอาร์กิวเมนต์aเป็นชนิดint และค่าที่คืนกลับเป็นชนิดstr
def greet(age: int) -> str:
    return f"Your age is {age}"
Type Hint ไม่ส่งผลต่อการทำงานขณะรันไทม์ แต่ช่วยให้อ่านโค้ดได้ง่ายขึ้น และเมื่อทำงานร่วมกับระบบเติมโค้ดอัตโนมัติของเอดิเตอร์ก็จะช่วยเพิ่มประสิทธิภาพการพัฒนา

3. การใช้งานโมดูล typing

โมดูล typing ของ Python ใช้เพื่อแสดงชนิดข้อมูลที่ซับซ้อนมากขึ้น ต่อไปนี้คือชนิดข้อมูลที่นิยมใช้กันทั่วไปบางส่วน

ตัวอย่างการใช้งานชนิดข้อมูล List

หากต้องการกำหนดชนิดให้กับลิสต์ ให้ใช้ List ตัวอย่างต่อไปนี้แสดงลิสต์ของชนิด int:
from typing import List

numbers: List[int] = [1, 2, 3, 4, 5]
ตั้งแต่ Python 3.9 ขึ้นไป สามารถใช้ list แทน List ได้
numbers: list[int] = [1, 2, 3, 4, 5]

การใช้งานชนิดข้อมูล Dict

ชนิดดิกชันนารีก็สามารถใส่ type hint ได้เช่นกัน ตัวอย่างต่อไปนี้คือดิกชันนารีที่คีย์เป็น str และค่ามีชนิด int:
from typing import Dict

inventory: Dict[str, int] = {"apple": 10, "banana": 5}

การใช้ Union

เมื่อมีความเป็นไปได้ว่าจะมีหลายชนิด ให้ใช้ Union ตัวอย่างด้านล่างแสดงว่าพารามิเตอร์อาจเป็นชนิด str หรือ int:
from typing import Union

def process(value: Union[int, str]) -> None:
    if isinstance(value, int):
        print(f"Integer: {value}")
    else:
        print(f"String: {value}")
ดังนั้น การใช้โมดูล typing ช่วยให้ใส่ type hint ได้ยืดหยุ่นและเข้าใจง่ายยิ่งขึ้น

4. ตัวอย่างการใช้ type hint ขั้นสูง

Type hint รองรับโครงสร้างข้อมูลและฟังก์ชันที่ซับซ้อนมากขึ้นด้วย ในที่นี้เราจะแนะนำฟังก์ชันที่มีค่าที่ส่งกลับหลายค่าและวิธีสร้างชนิดแบบกำหนดเอง

การระบุชนิดของค่าที่ส่งกลับหลายค่า

เมื่อฟังก์ชันส่งกลับหลายค่า ให้ใช้ tuple เพื่อระบุชนิดของค่าที่ส่งกลับ
def get_coordinates() -> tuple[float, float]:
    return 35.6895, 139.6917
การทำเช่นนี้ช่วยระบุชนิดของค่าที่ส่งกลับอย่างชัดเจน และเพิ่มความอ่านง่ายของโค้ด

การกำหนดชนิดแบบกำหนดเอง

การใช้ NewType จะช่วยให้สามารถสร้างชนิดแบบกำหนดเองได้ ตัวอย่างเช่น ในตัวอย่างต่อไปนี้ได้กำหนดชนิดใหม่ที่ชื่อว่า UserId
from typing import NewType

UserId = NewType('UserId', int)

def get_user(user_id: UserId) -> str:
    return f"User ID is {user_id}"
การกำหนดชนิดแบบกำหนดเองช่วยให้ความหมายของโค้ดชัดเจนขึ้น และสื่อเจตนาได้ง่ายขึ้น

5. วิธีใช้เครื่องมือตรวจสอบชนิดข้อมูล

นอกจากการใช้ type hint แล้ว การใช้เครื่องมือตรวจสอบชนิดแบบสถิตจะช่วยให้เขียนโค้ดที่เชื่อถือได้มากขึ้น เครื่องมือที่นิยมได้แก่mypyและPylance

mypy การติดตั้งและการใช้งาน

mypy เป็นหนึ่งในเครื่องมือตรวจสอบชนิด โดยจะตรวจสอบข้อผิดพลาดตาม type hint ที่อยู่ในโค้ด Python ก่อนอื่นให้ติดตั้งก่อน。
pip install mypy
จากนั้นให้รันการตรวจสอบชนิด
mypy script.py
ด้วยวิธีนี้ หากมีความไม่สอดคล้องของชนิดข้อมูลหรือมีปัญหา จะมีการแจ้งเตือน

Pylance สำหรับการตรวจสอบชนิดแบบเรียลไทม์

ส่วนขยายของ VSCode อย่างPylance รองรับการตรวจสอบชนิดแบบเรียลไทม์ ตัวอย่างเช่น จะมีการแสดงข้อความข้อผิดพลาดในตัวแก้ไขตาม type hint และสามารถแก้ไขปัญหาได้ทันที
def add_numbers(a: int, b: int) -> str:
    return a + b  # ตรงนี้จะแสดงข้อผิดพลาดและแนะนำให้แก้ไข
เนื่องจากสามารถตรวจสอบข้อผิดพลาดแบบเรียลไทม์ได้ ความเร็วในการพัฒนาจึงเพิ่มขึ้น และช่วยป้องกันบั๊กได้ตั้งแต่เนิ่นๆ

6. การใช้ไทป์ฮินต์ในโปรเจ็กต์จริง

ไทป์ฮินต์มีประโยชน์อย่างยิ่งในโปรเจ็กต์จริงด้วยเช่นกัน ที่นี่เราจะแนะนำตัวอย่างการใช้งานจริงในโปรเจ็กต์

ความสำคัญของไทป์ฮินต์ในการพัฒนาทีม

ไทป์ฮินต์มีประสิทธิภาพอย่างยิ่งในงานพัฒนาทีมและโปรเจ็กต์โอเพ่นซอร์ส ตัวอย่างโค้ดด้านล่างเป็นฟังก์ชันที่ดึงข้อมูลจาก API แล้วนำไปประมวลผล
from typing import Dict, Any

def fetch_data() -> Dict[str, Any]:
    return {"status": 200, "data": {"user": "Alice", "age": 30}}
ดังที่เห็น เมื่อใช้ไทป์ฮินต์เพื่อทำให้โครงสร้างข้อมูลชัดเจนขึ้น นักพัฒนาคนอื่นๆ จะเข้าใจโค้ดได้ง่ายขึ้น

การตรวจสอบความถูกต้องโดยใช้ไทป์ฮินต์

ไทป์ฮินต์ยังช่วยในการตรวจสอบความถูกต้องของข้อมูลด้วย ฟังก์ชันด้านล่างตรวจสอบว่าองค์ประกอบทุกตัวของลิสต์เป็นสตริง
from typing import List

def validate_strings(values: List[str]) -> bool:
    return all(isinstance(v, str) for v in values)
การใช้ไทป์ฮินต์ช่วยเพิ่มความถูกต้องของโค้ดและป้องกันบั๊กได้ตั้งแต่เนิ่นๆ

ความสะดวกในการรีแฟกเตอร์โดยใช้ไทป์ฮินต์

การใช้ไทป์ฮินต์มีประโยชน์มากในช่วงรีแฟกเตอร์โค้ด รีแฟกเตอร์คือการปรับปรุงโค้ดโดยไม่เปลี่ยนการทำงานของโปรแกรม โดยเฉพาะเมื่อเป็นฟังก์ชันที่มีอาร์กิวเมนต์หรือค่าที่ส่งกลับจำนวนมาก หรือจัดการกับโครงสร้างข้อมูลที่ซับซ้อน ไทป์ฮินต์จะเป็นแนวทางช่วยป้องกันความผิดพลาด ตัวอย่างเช่น มาดูโค้ดต่อไปนี้
def process_data(data: dict) -> None:
    # เนื้อหาการประมวลผล
    pass
โค้ดนี้เป็นฟังก์ชันที่รับดิกชันนารีแบบง่ายเท่านั้น แต่หากโครงสร้างข้อมูลซับซ้อนขึ้น หรืออาจได้รับข้อมูลคนละชนิด ก็มีความเสี่ยงที่จะทำการเปลี่ยนแปลงผิดพลาดระหว่างการรีแฟกเตอร์ การระบุชนิดให้ชัดเจนด้วยไทป์ฮินต์ดังต่อไปนี้ จะช่วยให้สามารถรีแฟกเตอร์ได้อย่างปลอดภัยแม้มีการเปลี่ยนแปลงโค้ด
from typing import Dict, Union

def process_data(data: Dict[str, Union[str, int]]) -> None:
    # เนื้อหาการประมวลผล
    pass
ในกรณีนี้ มีการกำหนดชนิดเป็น Dict[str, Union[str, int]] ดังนั้นแม้จะรีแฟกเตอร์ ระบบตรวจสอบชนิดข้อมูล (เช่น mypy) จะช่วยตรวจพบข้อผิดพลาดล่วงหน้าและป้องกันบั๊กที่ไม่คาดคิดได้

7. สรุป

type hint ของ Python เป็นเครื่องมือที่ทรงพลังมาก โดยเฉพาะอย่างยิ่งในโปรเจ็กต์ขนาดใหญ่และการพัฒนาของทีม ช่วยเพิ่มความสามารถในการอ่านและการบำรุงรักษา การใช้ประโยชน์จาก type hint ช่วยป้องกันบั๊กตั้งแต่เนิ่นๆ และยกระดับคุณภาพของโค้ด นอกจากนี้ การใช้เครื่องมือตรวจสอบชนิดแบบสถิตอย่างmypyและPylanceจะช่วยตรวจจับข้อผิดพลาดของชนิดล่วงหน้าในกระบวนการพัฒนา และแก้ไขได้อย่างมีประสิทธิภาพ。 โดยเฉพาะอย่างยิ่ง type hint มีประโยชน์ในด้านต่อไปนี้。
  • เพิ่มความสามารถในการอ่านของโค้ด ทำให้นักพัฒนาคนอื่นเข้าใจได้รวดเร็วยิ่งขึ้น。
  • สามารถทำรีแฟกเตอร์ได้อย่างปลอดภัย จึงคงคุณภาพของโค้ดไว้ได้เมื่อโปรเจ็กต์ดำเนินไป。
  • ด้วยการใช้ประโยชน์จากเครื่องมือตรวจสอบชนิดแบบสถิต สามารถค้นพบและแก้ไขข้อผิดพลาดได้ตั้งแต่เนิ่นๆ。
ต่อไป หากนำ type hint มาใช้ในโปรเจ็กต์ Python อย่างจริงจัง คุณจะสามารถสร้างโค้ดที่แข็งแกร่งและเข้าใจได้ง่ายยิ่งขึ้น