Khóa học
Python đã giành giải thưởng "Ngôn ngữ của Năm" của TIOBE ba lần trong bốn năm gần đây. Ngôn ngữ lập trình phổ biến này vẫn đứng đầu chỉ số TIOBE vào giữa năm 2022.

Python đứng đầu chỉ số TIOBE cho tháng 6 năm 2022.
Python đạt mức xếp hạng 12,74% có nghĩa là từ khóa “Python” xuất hiện trong khoảng ~13% tổng số truy vấn trên công cụ tìm kiếm liên quan đến lập trình. Nói cách khác, cứ 7 hoặc 8 câu hỏi về lập trình trên Internet thì có một câu liên quan đến Python.
Ngày nay, Python thường gắn liền với những đột phá lớn trong khoa học dữ liệu và AI. Người dùng đánh giá cao sự đơn giản, hệ sinh thái thư viện tích hợp và bên thứ ba phong phú cho nhiều tác vụ, cùng cộng đồng của nó.
Với bản ổn định cuối cùng của 3.11 ra mắt vào ngày 3 tháng 10 năm 2022, cộng đồng Python có thể mong đợi nhiều cập nhật đáng hoan nghênh, bao gồm tăng tốc độ đáng kể, xử lý và gỡ lỗi lỗi tốt hơn, cùng nhiều cải tiến nhỏ cho các thư viện chuẩn.
Những tính năng mới của Python 3.11 là gì?
Changelog của Python 3.11 bao gồm một danh sách gần như bất tận các bản sửa lỗi, cải tiến và bổ sung, phần lớn trong số đó bạn có thể sẽ không để ý. Tuy nhiên, một vài tính năng mới quan trọng có thể cải thiện đáng kể quy trình làm việc với Python khi bản phát hành ổn định xuất hiện. Những tính năng này được nêu dưới đây.
1. Cải thiện tốc độ
Thay đổi lớn đầu tiên khiến các nhà khoa học dữ liệu hào hứng là cải thiện tốc độ—bộ kiểm thử chuẩn chạy nhanh hơn khoảng 25% so với 3.10. Tài liệu Python cho biết 3.11 có thể nhanh hơn tới 60% trong một số trường hợp. Dưới đây là cách tự thực hiện bài kiểm thử benchmark để bạn tự kiểm tra mức cải thiện tốc độ.
Để so sánh tốc độ của Python 3.10 và 3.11, bạn sẽ cần cài đặt Docker. Sau khi đảm bảo Docker Desktop đang chạy, hãy chạy hai lệnh này trong terminal; chúng sẽ tải về hai image cho hai phiên bản Python.
$ docker run -d python:3.10.4-bullseye
$ docker run -d python:3.11-rc-bullseye
Các image đã tải sẽ hiển thị trong bảng điều khiển Docker của bạn, nơi bạn cũng có thể khởi chạy chúng.

Sau khi khởi chạy các container, bạn có thể chạy docker ps để xem các chi tiết như ID container, image, trạng thái và hơn thế nữa.

Các container đang chạy cũng hiển thị dưới tab Containers trong bảng điều khiển của bạn, nơi bạn sẽ thấy các nút CLI cạnh "Run/Stop". Nhấn vào chúng cho cả hai container để mở hai tab terminal gắn với các container.
Trong cả hai tab, cài đặt gói pyperformance qua pip. Sau đó, chạy các lệnh dưới đây trong mỗi terminal của container.
Với Python 3.10
$ pyperformance run -r -o py310.json
Với Python 3.11
$ pyperformance run -r -o py310.jsone run -r -o py311.json
Các lệnh này sẽ chạy kiểm thử benchmark cho khoảng 60 hàm Python từ các thư viện chuẩn và tạo ra metadata JSON. Tôi tùy chọn thêm thẻ -r để báo cho pyperformance rằng tôi muốn bài kiểm thử nghiêm ngặt hơn, tốn thêm thời gian. Trường hợp của tôi, cả hai container chạy trên máy Windows với CPU AMD Ryzen 12 lõi.
Bây giờ, chúng ta có hai tệp JSON trong hai container, và cần đặt cả hai vào cùng một thư mục để tiếp tục kiểm thử tốc độ. Để làm vậy, chúng ta sẽ dùng lệnh docker cp để sao chép tệp JSON từ container Python 3.11 sang 3.10.
Chạy các lệnh dưới đây trong một tab terminal riêng, cập nhật đường dẫn cho phù hợp với máy của bạn:
$ docker cp crazy_snyder:/py311.json C:/Users/bex/Desktop
$ docker cp C:/Users/bex/Desktop/py311.json charming_proskuriakova:/
Trong trường hợp của tôi, crazy_snyder và charming_proskuriakova là ID của các container đang chạy. Giờ thì cả hai tệp JSON đều nằm trong container Python 3.10. Để hoàn tất bài benchmark và lưu kết quả thành CSV, chạy các lệnh dưới đây.
$ pyperformance compare py310.json py311.json --csv comparison.csv
$ docker cp charming_proskuriakova:/comparison.csv C:/Users/bex/Desktop/articles
Cuối cùng, hãy nạp tệp CSV vào Pandas và phân tích:
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
df = pd.read_csv("data/comparison.csv")
df.rename({"Base": "py310", "Changed": "py311", "Benchmark": "function"},
axis=1,
inplace=True)
>>> df.shape
(59, 3)
>>> df.sample(5)
| Hàm | py310 | py311 | |
| 40 | scimark_monte_carlo |
0.12392 | 0.08052 |
| 19 | mako |
0.01967 | 0.01289 |
| 1 | chameleon |
0.01131 | 0.00843 |
| 8 | float |
0.14265 | 0.09133 |
| 35 | regex_effbot |
0.00315 | 0.00261 |
Mỗi hàng trong dataframe ghi lại mất bao nhiêu thời gian (tính bằng mili giây) để cả hai phiên bản chạy hàm Python đã cho. Hãy vẽ biểu đồ histogram của mức tăng tốc.
df["speed_up"] = (df["py310"] / df["py311"]).round(3)
fig, ax = plt.subplots()
sns.histplot(df["speed_up"], bins=11)
ax.set(xlabel="Speedup (times)",
title="Python 3.10 vs. Python 3.11 - speedup comparison")
plt.show()

Từ biểu đồ có thể thấy đa số các hàm trong Python 3.11 nhanh hơn khoảng 1,2 lần (20%). Ta cũng có thể xác nhận ước lượng này bằng giá trị trung bình và trung vị.
>>> df["speed_up"].mean()
1.2605593220338982
>>> df["speed_up"].median()
1.207
Có vẻ có một trường hợp mức tăng tốc vượt quá 60%.
>>> df["speed_up"].max()
1.899
Cũng có bốn trường hợp Python 3.10 nhanh hơn phiên bản mới.
>>> (df["speed_up"] <= 1).sum()
4
Mặc dù mức tăng hiệu năng rõ rệt trên giấy tờ, tác động cụ thể sẽ khác nhau tùy người dùng và bản ổn định cuối cùng của Python 3.11 vẫn còn chưa phát hành. Bài benchmark sử dụng các hàm thuần Python, có thể bạn không dùng nhiều trong công việc hằng ngày, nhưng thiết lập Docker cho cả Python 3.10 và 3.11 sẽ giúp bạn hình dung mức tăng tốc cho các trường hợp sử dụng cụ thể của mình.
2. Thông báo lỗi tốt hơn
Một tính năng thú vị khác của Python 3.11 là thông báo lỗi tốt hơn, chỉ ra chính xác vị trí xảy ra lỗi. Thay vì trả về một traceback 100 dòng kết thúc bằng thông báo lỗi khó hiểu, Python 3.11 trỏ đến đúng biểu thức gây ra lỗi.

Trong ví dụ trên, trình thông dịch Python trỏ đến x khiến script sập do giá trị None của nó. Lỗi này sẽ mơ hồ trong các phiên bản hiện tại của Python vì có hai đối tượng với thuộc tính ‘x’. Tuy nhiên, xử lý lỗi của 3.11 chỉ rõ biểu thức có vấn đề.
Ví dụ này cho thấy 3.11 xác định lỗi từ một dictionary lồng sâu và có thể chỉ rõ khóa nào gây lỗi.

Bạn có thể thấy độ chính xác tương tự trong các biểu thức số học phức tạp.

Các thông báo lỗi được cập nhật chắc chắn là bổ sung đáng giá, đặc biệt cho các nhà khoa học dữ liệu thường gặp khó khăn khi gỡ lỗi script.
3. Ghi chú ngoại lệ (Exception Notes)
“Rõ ràng tốt hơn hàm ý.”
Câu trên là dòng thứ hai trong Zen of Python, danh sách 20 nguyên lý thiết kế của Python. Điều này thể hiện quy tắc mã Python nên biểu đạt rõ ràng nhất có thể.
Để củng cố mẫu thiết kế này, Python 3.11 giới thiệu ghi chú ngoại lệ (PEP 678). Giờ đây, bên trong các mệnh đề except, bạn có thể gọi hàm add_note() và truyền một thông điệp tùy chỉnh khi bạn raise lỗi.
import math
try:
math.sqrt(-1)
except ValueError as e:
e.add_note("Negative value passed! Please try again.")
raise

Nếu bạn đã viết một lớp ngoại lệ tùy chỉnh như dưới đây, bạn có thể thêm nhiều ghi chú vào lớp bên trong thuộc tính cấp lớp được bảo vệ __notes__:
import math
class MyOwnError(Exception):
# Should be a list of strings
__notes__ = ["This is a custom error!"]
try:
math.sqrt(-1)
except:
raise MyOwnError

Bây giờ, khi trình thông dịch gặp lỗi, nó sẽ hiển thị thông điệp tùy chỉnh sau phần nội dung thông điệp thông thường.
Cũng có cú pháp mới để raise ngoại lệ với mệnh đề except*, được dùng cùng với lớp ExceptionGroup mới. PEP 654 cho biết bạn có thể dùng nó để raise đồng thời nhiều lỗi không liên quan trong các tình huống khác nhau. Phần lớn các tình huống này khá đặc thù, như làm việc với web sockets, lập trình đồng thời với asyncio, v.v., ít khi xuất hiện trong công việc khoa học dữ liệu hằng ngày, nhưng nếu bạn quan tâm, bạn có thể tìm hiểu cú pháp mới tại đây.
4. Tính năng typing mới: Self
Các ngôn ngữ kiểu tĩnh giúp mã của bạn dễ đọc và dễ gỡ lỗi. Xác định chính xác kiểu của biến, đầu vào và đầu ra của hàm có thể giúp bạn tiết kiệm hàng giờ gỡ lỗi và giúp người khác dễ đọc mã của bạn hơn. Thêm chú thích kiểu cũng cho phép các IDE hiện đại hiển thị định nghĩa hàm khi bạn gõ tên, giúp người khác dễ hiểu hàm của bạn.
Cho đến nay, mô-đun typing mạnh mẽ của Python có lớp cho hầu như mọi kiểu dữ liệu, ngoại trừ các lớp trả về chính thể hiện của chúng. Ở các phiên bản Python hiện tại, ví dụ dưới đây không khả thi:
from typing import Self
class Language:
def __init__(self, name, version, release_date):
self.name = name
self.version = version
self.release_date = release_date
def change_version(self, version) -> Self:
self.version = version
return Language(self.name, self.version, self.release_date)

Tuy nhiên, Python 3.11 giới thiệu lớp Self, bạn có thể thêm vào định nghĩa hàm nếu giá trị trả về là self hoặc một thể hiện mới của chính lớp đó.
5. Cải tiến cho các thư viện chuẩn
Có một vài cải tiến hữu ích khác cho các thư viện chuẩn. Trước hết, hai hàm được mong chờ từ lâu đã được thêm vào mô-đun math.
>>> import math
>>> math.cbrt(9) # Find the cube-root of x
2.080083823051904
>>> math.cbrt(27)
3.0000000000000004
>>> math.exp2(5) # Raise 2 to the power of x
32.0
Việc Python mất 28 năm để thêm hàm căn bậc ba quả là đáng ngạc nhiên, nhưng như người ta vẫn nói, muộn còn hơn không.
Mô-đun fractions cũng bổ sung tính năng mới cho phép bạn tạo phân số từ chuỗi:
>>> from fractions import Fraction
>>> Fraction("22/7") # New in Python 3.11
Fraction(22, 7)
>>> Fraction(numerator=22, denominator=7)
Fraction(22, 7)
>>> Fraction("3e-4")
Fraction(3, 10000)
>>> Fraction("-73/41")
Fraction(-73, 41)
>>> Fraction(3.1415) # Find the closest approximation to the given float
Fraction(7074029114692207, 2251799813685248)
Như bạn thấy, mô-đun fractions có thể hữu ích cho một số phép toán số học. Tôi đặc biệt thích cách bạn có thể tìm phân số gần nhất xấp xỉ số thực đã cho. Bạn có thể tiến xa hơn bằng cách đặt giới hạn mẫu số:
>>> from math import pi
>>> Fraction(pi).limit_denominator(100000)
Fraction(312689, 99532)
Cũng có một mô-đun mới tên là tomllib để phân tích cú pháp tài liệu TOML. TOML (Tom's Obvious Minimal Language) là định dạng tệp phổ biến để viết các tệp cấu hình dễ đọc cho con người. Dưới đây là một hình ảnh từ trang chủ của dự án:

import tomllib
toml_str = """
python-version = "3.11.0"
release_date = "2022-10-22"
"""
data = tomllib.loads(toml_str)
print(data) # {'python-version': '3.11.0', 'release_date': '2022-10-22'}
print(data['python-version']) # 3.11.0
print(data['release_date']) # 2022-10-22
Ngày phát hành Python 3.11
Việc phát triển Python 3.11 bắt đầu vào ngày 5 tháng 5 năm 2021. Kể từ đó, bảy bản alpha đã được phát hành, trùng với bản beta đầu tiên vào ngày 8 tháng 5 năm 2022. Từ thời điểm này cho đến khi phát hành chính thức sẽ không có tính năng mới nào được thêm vào Python.
Bản phát hành ổn định cuối cùng sẽ ra mắt vào ngày 3 tháng 10 năm 2022, sau ba bản beta nữa và hai bản candidate trong thời gian giữa. Bạn có thể tìm hiểu thêm về Python qua các tài nguyên sau.