Python 3.12 beta 1 vừa được phát hành cách đây không lâu. Các developer được khuyến khích là nên dùng thử phiên bản mới này trên non-production code, vừa để xác minh rằng các program của bạn hoạt động tốt trên phiên bản này, vừa để biết liệu code có được hưởng lợi từ các bộ tính năng mới và cải tiến hiệu suất trong phiên bản mới nhất này hay không. 

Dưới đây là tóm tắt các tính năng mới quan trọng nhất trong Python 3.12 và ý nghĩa của chúng đối với các lập trình viên Python. 

1. Thông báo về lỗi tốt hơn

Các thông báo về lỗi ngày càng tối ưu (cho biết chính xác dòng gặp lỗi) và chi tiết hơn (gợi ý nguyên do gặp lỗi). Bên cạnh đó, Python 3.12 còn mang đến những cải tiến bổ sung: 

  • Đề xuất module bị thiếu, bao gồm các module từ standard library

  • Đề xuất lỗi tốt hơn cho lỗi cú pháp phổ biến khi nhập; ví dụ: import p from m trả về lỗi gợi ý là from m import p.

2. Hỗ trợ cho Linux perf profiler

Công cụ Linux profiler perf đã có thể hoạt động trên Python, nhưng nó chỉ trả thông tin về những gì đang xảy ra ở cấp độ C trong thời gian chạy Python. Thông tin function về chương trình Python thực tế sẽ không được hiển thị.

Python 3.12 kích hoạt chế độ opt-in cho phép perf thu thập data chi tiết về các chương trình Python. Chế độ opt - in có thể được thực hiện ở cấp độ môi trường hoặc bên trong chương trình Python có function sys.activate_stack_trampoline.

3. Giám sát debug/profile nhanh hơn

Chạy profiler hay đính kèm trình debug vào chương trình Python sẽ cho bạn biết khả năng hiển thị và thông tin chi tiết về hoạt động của chương trình đó. Tuy nhiên việc này sẽ đi kèm với một chi phí hiệu suất. Dẫn đến việc các chương trình chạy chậm hơn.

Vì thế Pep 669 đã cung cấp các hook cho các event code object mà profiler và trình debug có thể đính kèm vào, chẳng hạn như điểm bắt đầu hoặc điểm kết thúc của một function, giúp giảm bớt được chi phí và không làm ảnh hưởng nhiều đến hiệu suất chương trình.

4. Cải tiến typing

TypedDict

Trong Python 3.12, bạn có thể sử dụng TypedDict làm source của các type để gợi ý các kwargs (đối số từ khóa) được sử dụng trong một function. Unpack variadic generic được sử dụng cho việc này từng được giới thiệu trong phiên bản 3.11. Đây là một ví dụ:

class Movie(TypedDict):
    name: str
    year: int

def foo(**kwargs: Unpack[Movie]) -> None: ...

Tại đây, foo có thể nhận kwargs của “names” và “type” phù hợp với nội dung của Moviename:str year:int. Việc này giúp ích trong việc type-hinting functions các đối số chỉ từ khóa tùy chọn mà không có giá trị mặc định.

Type parameter syntax

Type parameter syntax rõ ràng hơn trong việc chỉ định các type trong một class, function hoặc type alias. Đây là một ví dụ lấy từ PEP:

# the old method 

from typing import TypeVar

_T = TypeVar("_T")

def func(a: _T, b: _T) -> _T:
    ...

# the new type parameter method

def func[T](a: T, b: T) -> T:
    ...

Với phương pháp mới, người ta không cần nhập tệp TypeVar. Mà có thể sử dụng cú pháp func[T để chỉ ra các type references. Cũng có thể chỉ định type bounds, chẳng hạn như liệu một type nhất định có phải là một trong một nhóm các type hay không, mặc dù chúng không phải là generic type. Ví dụ như func[T: (str,int)].

5. Cải tiến hiệu suất

Tuy những cải tiến này không quá ấn tượng nhưng cũng có một vài điểm đáng chú ý sau:

Comprehension inlining

Một cú pháp cho phép bạn nhanh chóng tạo list, dictionaries và set, hiện chúng có thể được tạo bằng "inline" thay vì object temporary. Theo đó, kiểm tra speedup có thể đạt đến khoảng 11% đối với trường hợp trong real-world và nhanh gấp đôi đối với micro-benchmark.

Immortal objects

Mọi object trong Python đều có số lượng tham chiếu theo dõi số lần các object khác tham chiếu đến nó, bao gồm các object tích hợp sẵn như None. PEP 683 cho phép các object được coi là "immortal", để chúng không bao giờ bị thay đổi số lượng tham chiếu.

Về lâu dài các immortal object sẽ vô cùng hữu ích. Nó làm cho việc triển khai thay đổi multicore scaling trở nên dễ dàng hơn và triển khai các optimizations khác (như tránh copy-on-write ) mà trước đây rất khó thực hiện.

Size object nhỏ hơn

Với các phiên bản Python trước đó, size tiêu chuẩn của một object là 208 byte. Các object đã được tái cấu trúc nhiều lần trong một số phiên bản Python gần đây nhất để làm cho chúng nhỏ hơn, điều này không chỉ cho phép nhiều object live trong bộ nhớ mà còn giúp định vị bộ đệm. Kể từ Python 3.12, size tiêu chuẩn của một object hiện là 96 byte—ít hơn một nửa so với trước đây.

Subinterpreters

Một tính năng đã được chờ đợi từ lâu của Python là subinterpreters — khả năng có nhiều phiên bản interpreter, mỗi phiên bản có GIL riêng, chạy song song trong một quy trình Python. Đây sẽ là một bước tiến lớn hướng tới tính parallelism trong Python.

Tuy nhiên, phiên bản 3.12 chỉ bao gồm các thành phần trong CPython. Vẫn chưa có giao diện người dùng cuối cho các subinterpreters. Một library module tiêu chuẩn, interpreters, đã được thiết kế để thực hiện việc này, dự kiến nó ​​sẽ xuất hiện trong Python 3.13.

6. Một vài thay đổi bổ sung

Unstable API

Đây là một bộ API được đánh dấu cụ thể là có khả năng thay đổi giữa các phiên bản. Nó được sử dụng bởi các công cụ cấp thấp như trình debug hoặc trình biên dịch JIT.

Ngừng sử dụng và xóa library standard

Với phiên bản 3.11, một số module library standard đã lỗi thời từ lâu đã bị gắn flag để xóa kể từ Python 3.12 và 3.13. Trong phiên bản 3.12, một trong những lần xóa lớn nhất là distutils, mà từ lâu đã được setuptools. Các module khác bị loại bỏ trong phiên bản này asynchat, asyncore(cả hai đều được thay thế bằng asyncio) và smtpd.

Garbage collection

Cơ chế Garbage Collection của Python từng có thể chạy bất cứ khi nào một object được phân bổ. Kể từ Python 3.12, GC chỉ chạy trên cơ chế "eval breaker" trong vòng lặp bytecode của Python—nghĩa là, giữa việc thực thi bytecode này và bytecode khác. Nó cũng chạy bất cứ khi nào cơ chế kiểm tra xử lý tín hiệu của CPython được gọi. 

VietnamWorks inTECH