คุณสมบัติล่าสุดของ Python

คุณสมบัติล่าสุดของ Python

บทความนี้อธิบายคุณสมบัติล่าสุดของ Python

เราจะอธิบายคุณสมบัติที่โดดเด่นของ Python รุ่น 3.12 ถึง 3.13 ทีละขั้นตอนจากมุมมองเชิงปฏิบัติที่สามารถนำไปใช้ได้ทันที

YouTube Video

คุณสมบัติล่าสุดของ Python

ในช่วงไม่กี่ปีที่ผ่านมา Python ได้พัฒนาโดยเน้นทั้งในด้าน 'ความง่ายในการเขียน' และ 'ความแข็งแกร่ง ความเร็ว และความอ่านง่าย' ด้านล่างนี้ เราจะแนะนำคุณสมบัติที่โดดเด่นของ Python รุ่น 3.12 ถึง 3.13

การปรับปรุงข้อความข้อผิดพลาดอย่างมาก (Python 3.12)

ใน Python 3.12 ข้อผิดพลาดจะแสดงอย่างชัดเจนและเห็นภาพมากขึ้น คุณสามารถระบุจุดที่เกิดข้อผิดพลาดได้ทันทีและลดเวลาในการดีบักลงอย่างมาก

1def calc_total(price, tax):
2    return price + price * tax
3
4result = calc_total(100, )
  • อาร์กิวเมนต์ที่หายไปจะแสดงพร้อมบรรทัดและตำแหน่งที่เกี่ยวข้อง ทำให้ไม่สับสนในการหาสาเหตุของปัญหา

การใช้คำสั่ง 'match' ในทางปฏิบัติ (Structural Pattern Matching)

คำสั่ง 'match' ช่วยให้คุณสามารถเขียนเงื่อนไขที่ซับซ้อนและตรวจสอบโครงสร้างข้อมูลได้อย่างชัดเจน การจัดการ dictionaries และโครงสร้างข้อมูลที่ซ้อนกันจะอ่านง่ายขึ้นเป็นพิเศษ

1user = {"status": "active", "name": "Alice"}
2
3match user:
4    case {"status": "active", "name": name}:
5        print(f"Welcome back, {name}!")
6    case {"status": "inactive"}:
7        print("Please activate your account.")
8    case _:
9        print("Unknown user status.")
  • เนื่องจากสามารถแยกเงื่อนไขและดึงข้อมูลในเวลาเดียวกัน การซ้อน if statement จึงไม่จำเป็นอีกต่อไป

จับคู่รูปแบบอย่างเป็นธรรมชาติสำหรับการจัดการข้อมูลที่ซ้อนกัน

คำสั่ง 'match' ยังมีประสิทธิภาพในการจัดการข้อมูลโครงสร้าง เช่น JSON หรือการตอบกลับของ API

1data = {"user": {"name": "Bob", "age": 25}}
2
3match data:
4    case {"user": {"name": name, "age": age}}:
5        print(f"{name} is {age} years old.")
  • คุณสามารถดึงเฉพาะส่วนที่ต้องการได้อย่างปลอดภัย ลดความจำเป็นในการเขียนโค้ดป้องกันข้อผิดพลาด

ปรับปรุงการแสดงผลดีบักด้วย f-string (สัญลักษณ์ =` / Python 3.8 ขึ้นไป ใช้ง่ายขึ้น)

ด้วย f-string คุณสามารถ เพิ่ม = เพื่อแสดงทั้งนิพจน์และค่าที่ได้พร้อมกัน คุณสมบัตินี้เฉพาะสำหรับการดีบักและมีประโยชน์มากเมื่อคุณต้องการตรวจสอบค่าตัวแปรอย่างรวดเร็ว

1x = 10
2y = 20
3print(f"{x=}, {y=}, {x+y=}")
  • เนื่องจากชื่อและค่าของตัวแปรจะแสดงพร้อมกัน การดีบักเบื้องต้นด้วย print() จะอ่านง่ายขึ้น
  • คุณสามารถเขียนโค้ดสำหรับแสดง log และตรวจสอบข้อมูลได้กระชับและแสดงเจตนาได้ชัดเจนขึ้น

รูปแบบ Type Hint และ 'type' alias ที่ง่ายขึ้น (Python 3.12: ไวยากรณ์ใหม่สำหรับ type alias)

ใน Python 3.12 ได้มีการแนะนำ ไวยากรณ์เฉพาะทางสำหรับการกำหนด type alias คือคำสั่ง type สิ่งนี้ทำให้ type hint ไม่ใช่เพียงข้อมูลเสริมแต่เป็น องค์ประกอบของภาษาเพื่อแสดงเจตนาทางการออกแบบได้ชัดเจน

1type UserId = int
2type UserName = str
3
4def greet(user_id: UserId, name: UserName) -> str:
5    return f"Hello, {name} (id={user_id})"
  • ด้วยการกำหนดความหมายให้กับ UserId หรือ UserName จะเห็นความแตกต่างของหน้าที่ แม้ว่าทั้งคู่จะใช้ int หรือ str ก็ตาม
  • การนิยามประเภทจะกระชับมากขึ้น ลดภาระในการทำความเข้าใจระหว่างตรวจสอบและดูแลรักษาโค้ด
  • ก่อนหน้านี้ type alias เช่น UserId = int จะถูกกำหนดด้วยการ assign แต่การใช้คำสั่ง type ทำให้ชัดเจนทันทีว่า 'นี่คือการนิยามประเภท' สิ่งนี้มีประสิทธิผลอย่างยิ่งในการปรับปรุงความอ่านง่ายของโครงสร้างโค้ดขนาดกลางและขนาดใหญ่

การระบุประเภท (Type Annotation) ที่เป็นธรรมชาติด้วย built-in types (Generics ที่ง่ายขึ้นใน Python 3.9 ขึ้นไป)

ตั้งแต่ Python 3.9 คุณสามารถ ใช้ built-in types เช่น list หรือ dict ในการกำหนด generics ได้โดยตรง

สิ่งนี้ทำให้คุณสามารถเขียน type hint ได้เป็นธรรมชาติและอ่านง่ายโดยไม่ต้องนำเข้า types จากโมดูล typing

1def sum_numbers(numbers: list[int]) -> int:
2    return sum(numbers)
3
4print(sum_numbers([1, 2, 3, 4]))
  • Type hint ทำงานไม่ใช่เป็น 'ข้อจำกัด' แต่เป็น 'เอกสารประกอบที่อธิบายขั้นตอนการประมวลผล'

การเชื่อมเมทอดอย่างปลอดภัยด้วย Self type (Python 3.11 ขึ้นไป)

ตั้งแต่ Python 3.11 คุณสามารถระบุ Self เป็น return type สำหรับเมทอดที่คืนค่าตัวเอง (คลาสเดียวกัน)

สิ่งนี้ช่วยให้คุณสามารถเขียนโค้ด method chaining ได้อย่างปลอดภัยโดยไม่สูญเสียข้อมูลประเภทของอินสแตนซ์

 1from typing import Self
 2
 3class Counter:
 4    def __init__(self, value: int = 0) -> None:
 5        self.value = value
 6
 7    def increment(self) -> Self:
 8        self.value += 1
 9        return self
10
11counter = Counter()
12counter.increment().increment()
13print(counter.value)
  • แม้จะเป็นเมทอดที่คืนค่า self ก็ ยังคงรักษาประเภทที่ถูกต้อง
  • IDE และตัวเช็คประเภทสามารถเข้าใจ method chaining ได้อย่างถูกต้อง

การจัดการสตริงที่ชัดเจนขึ้น (removeprefix / removesuffix | Python 3.9 ขึ้นไป)

ตั้งแต่ Python 3.9 ได้มีการเพิ่มเมทอด str.removeprefix() และ str.removesuffix() เพื่อ ลบคำหน้าหรือคำหลังออกจากสตริงอย่างปลอดภัย ด้วยเมทอดเหล่านี้ คุณสามารถแสดงเจตนาว่า 'ลบเฉพาะส่วนต้นหรือส่วนท้าย' ได้อย่างชัดเจนในโค้ด

1filename = "report_2026.txt"
2
3clean_name = filename.removeprefix("report_")
4name_without_ext = clean_name.removesuffix(".txt")
5
6print(name_without_ext)
  • สตริงที่ระบุจะถูกลบ ก็ต่อเมื่ออยู่ต้นหรือท้ายเท่านั้น จึงป้องกันการแทนที่โดยไม่ตั้งใจ
  • แนวทางนี้เพิ่มความอ่านง่ายและปลอดภัยกว่าการใช้ replace() หรือ slicing
  • โดยเฉพาะในการจัดการ 'สตริงที่มีรูปแบบเฉพาะ' เช่น ชื่อไฟล์ หรือการเตรียม URL การใช้เมทอดนี้จะ ลดความเสี่ยงของบั๊กได้มาก

การเปรียบเทียบสตริงที่แข็งแกร่งสำหรับ Internationalization (str.casefold() | รองรับ Unicode)

str.casefold() ใน Python คือเมทอดสำหรับ เปรียบเทียบสตริงโดยไม่สนใจตัวพิมพ์เล็ก-ใหญ่ พร้อมรองรับ Unicode ต่างจาก lower() หรือ upper() ที่ง่ายๆ มันจะปรับค่าปกติ (normalize) สตริง พร้อมทั้งแปลงอักขระเฉพาะภาษาด้วย

1text1 = "Stra\u00dfe"
2text2 = "strasse"
3
4print(text1)
5print(text2)
6
7print(f"Comparison Result: {text1.casefold() == text2.casefold()}")
  • สามารถจัดการกับ ความต่างที่ขึ้นอยู่กับภาษา เช่น เยอรมัน ß และ ss ได้อย่างเหมาะสม
  • นี่เป็นเทคนิคสำคัญสำหรับแอปพลิเคชันที่รองรับหลายภาษา หรือมีความต้องการด้าน internationalization

รองรับ TOML ในมาตรฐาน (tomllib | Python 3.11 ขึ้นไป)

ตั้งแต่ Python 3.11 เป็นต้นไป โมดูล tomllib สำหรับอ่านไฟล์ TOML จะถูกเพิ่มเข้าในไลบรารีมาตรฐาน การจัดการไฟล์ config สามารถทำได้ภายใน Python โดยไม่ต้องพึ่งไลบรารีภายนอก

 1import tomllib
 2
 3with open("config.toml", "rb") as f:
 4    config = tomllib.load(f)
 5
 6print(config["database"]["host"])
 7
 8# config.toml
 9# title = "TOML Example"
10# [database]
11# host = "192.168.1.1"
12# ports = [ 8001, 8001, 8002 ]
  • ไม่จำเป็นต้องใช้แพคเกจภายนอก เช่น toml อีกต่อไป ทำให้การจัดการ dependencies ง่ายขึ้น
  • การโหลดไฟล์ configuration จะเป็นมาตรฐานเดียวกัน เพิ่มความสะดวกในการแจกจ่าย การใช้งานจริง และในสภาพแวดล้อม CI

การจัดการข้อผิดพลาดสำหรับยุคประมวลผลขนาน (ExceptionGroup / except* | Python 3.11 ขึ้นไป)

Python 3.11 ได้เพิ่ม ExceptionGroup สำหรับจัดการข้อผิดพลาดหลายตัวพร้อมกัน และไวยากรณ์ except* เพื่อแยกจัดการข้อผิดพลาดแบบปลอดภัยเป็นกลุ่ม นี่คือคุณสมบัติใหม่สำหรับจัดการ 'ข้อผิดพลาดพร้อมกัน' ที่ปรากฏขึ้นในงานแบบ asynchronous หรือ parallel

 1def process(values):
 2    errors = []
 3    for v in values:
 4        if v < 0:
 5            errors.append(ValueError(f"Negative value: {v}"))
 6    if errors:
 7        raise ExceptionGroup("Invalid values", errors)
 8
 9try:
10    process([1, -2, -3])
11except* ValueError as e:
12    print("Handled:", e)
  • ข้อผิดพลาดหลายตัวสามารถ ถูกยกและแยกประเภทได้ในการดำเนินการเดียว
  • ช่วยแก้ปัญหาในงาน asynchronous ที่มักเห็นแค่ข้อผิดพลาดแรก
  • ใน operation เช่น asyncio.gather() หรือประมวลผล batch แบบขนาน อาจเกิดข้อผิดพลาดหลายอย่างพร้อมกัน การใช้ ExceptionGroup ทำให้ง่ายต่อการ เก็บข้อผิดพลาด บันทึก log และวางกลยุทธ์การ retry

ประสิทธิภาพดีขึ้นเพียงแค่เปลี่ยนมาใช้เวอร์ชันล่าสุด

ตั้งแต่ Python 3.11 เป็นต้นไป มีการเพิ่มประสิทธิภาพภายในจนหลายๆ กระบวนการทำงานเร็วขึ้น

1def count_up(n):
2    total = 0
3    for i in range(n):
4        total += i
5    return total
6
7print(count_up(1_000_000))
  • ข้อดีคือ เพิ่มความเร็วได้โดยไม่ต้องแก้ไขโค้ดเก่าเลย

ควบคุม Garbage Collection (จัดการชัดเจนผ่านโมดูล gc)

ใน Python คุณสามารถใช้ โมดูล gc มาตรฐาน เพื่อ ปิดการทำงานหรือรัน garbage collection ด้วยตนเองได้ นี่เป็นเทคนิคเพิ่มประสิทธิภาพที่มีประโยชน์ในกรณีเช่นการประมวลผลข้อมูลขนาดใหญ่หรือในงานที่ต้องการ performance สูง

1import gc
2
3gc.disable()
4# heavy batch processing
5gc.enable()
6gc.collect()
  • การลดการ trigger garbage collection ที่ไม่จำเป็นสามารถ ลดความผันผวนของเวลาประมวลผล
  • คุณสามารถสั่งเก็บขยะระหว่างแต่ละช่วงงาน ทำให้ติดตามการใช้เมมโมรี่ได้ง่ายขึ้น
  • อย่างไรก็ตาม เทคนิคนี้ไม่ควรใช้เป็นค่าเริ่มต้น แต่ ควรใช้ก็ต่อเมื่อ profiling พบว่า GC เป็นจุดคอขวดจริงๆ สำหรับแอปพลิเคชันส่วนใหญ่ การใช้ garbage collection อัตโนมัติของ Python นั้นปลอดภัยที่สุด

สรุป

ด้วยการปรับปรุงข้อความข้อผิดพลาดและการพัฒนา type hint ใน Python 3.12 - 3.13 ทำให้การเข้าใจและดูแลรักษาโค้ดง่ายขึ้นกว่าเดิม นอกจากนี้ การปรับปรุงประสบการณ์การดีบักและประสิทธิภาพการทำงานผ่านการ optimize ภายใน ล้วนส่งเสริมประสิทธิผลในทางปฏิบัติอย่างต่อเนื่อง คุณไม่จำเป็นต้องใช้ฟีเจอร์ใหม่ทั้งหมดพร้อมกัน ควรเริ่มต้นจาก Python รุ่นล่าสุด แล้วค่อยๆ นำฟีเจอร์ทีละอย่างมาใช้ตามความจำเป็น การนำฟีเจอร์มาใช้ทีละน้อยจะช่วยให้โค้ด Python อ่านง่ายและแข็งแกร่งยิ่งขึ้น

คุณสามารถติดตามบทความข้างต้นโดยใช้ Visual Studio Code บนช่อง YouTube ของเรา กรุณาตรวจสอบช่อง YouTube ด้วย

YouTube Video