คุณสมบัติล่าสุดของ 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 ด้วย