51 điểm bởi GN⁺ 2025-04-24 | 5 bình luận | Chia sẻ qua WhatsApp
  • Giới thiệu 14 tính năng nâng cao trong Python ít được biết đến, kèm theo ví dụ thực tế
  • Cung cấp phần giải thích chuyên sâu về typing tĩnh và thiết kế cấu trúc như typing, generics, protocols, context managers
  • Cũng bao gồm structural pattern matching mới được giới thiệu từ Python 3.10 trở lên, cùng các kỹ thuật tối ưu hiệu năng như slots và metaclass
  • Bao gồm các mẹo để viết mã gọn gàng hơn như f-string, cache, future, proxy, for-else, walrus
  • Mỗi tính năng đều có liên kết và tài liệu tham khảo để học thêm, với cách trình bày dễ tiếp cận ngay cả với lập trình viên junior

Tóm tắt 14 tính năng Python nâng cao

# Overload kiểu dữ liệu

  • Decorator @overload cho phép định nghĩa nhiều type signature cho một hàm
  • Trình kiểm tra kiểu có thể suy luận chính xác kiểu trả về theo giá trị đối số được truyền vào
  • Có thể dùng Literal để giới hạn giá trị chuỗi
  • Cũng có thể triển khai function signature chỉ yêu cầu một trong hai giá trị id hoặc username
  • Có thể dùng Literal như một phương án thay thế Enum nhẹ hơn để đảm bảo an toàn kiểu

# Đối số chỉ nhận theo từ khóa / chỉ nhận theo vị trí

  • Dùng * để đặt đối số chỉ nhận theo từ khóa (không thể dùng đối số vị trí)
  • Dùng / để đặt đối số chỉ nhận theo vị trí (không thể dùng đối số từ khóa)
  • Khi thiết kế API, có thể ép buộc rõ ràng cách sử dụng đối số

# Future annotations (__future__)

  • Type hint vốn được đánh giá ngay tại runtime nên có thể phát sinh vấn đề về thứ tự khai báo
  • Có thể trì hoãn thời điểm đánh giá bằng from __future__ import annotations
  • Tuy nhiên, vì hoạt động theo cách xử lý chuỗi nên cần cẩn thận khi dùng kiểu ở runtime
  • PEP 649 đề xuất cải tiến bằng cơ chế đánh giá trì hoãn cho thuộc tính __annotations__

# Cú pháp Generic

  • Từ Python 3.12, Python hỗ trợ cú pháp định nghĩa generic kiểu mới
  • Thay vì TypeVar, có thể dùng trực quan hơn với dạng class Foo[T, U: int]
  • Variadic Generics cũng được đưa vào, cho phép xử lý nhiều kiểu đa dạng
  • Cách định nghĩa type alias cũng gọn hơn, có thể dùng dạng type Vector = list[float]

# Protocols

  • Đây là phiên bản kiểm tra kiểu của Duck Typing, cho phép triển khai structural subtyping
  • Nếu một class có các method nhất định thì vẫn có thể tương thích kiểu mà không cần kế thừa kiểu
  • Có thể mở rộng để dùng với kiểm tra isinstance bằng @runtime_checkable

# Context Manager

  • Là đối tượng có các method __enter__, __exit__, được dùng trong khối with
  • Có thể triển khai đơn giản theo kiểu hàm bằng decorator contextlib.contextmanager
  • Có thể thực hiện thiết lập và dọn dẹp trước và sau yield

# Structural Pattern Matching

  • Cú pháp match-case giúp rẽ nhánh trực quan cho các cấu trúc dữ liệu phức tạp
  • Hỗ trợ destructuring tuple/list, OR pattern, điều kiện guard (if), và wildcard
  • Vì có thể rẽ nhánh dựa trên cấu trúc dữ liệu nên cải thiện khả năng đọc và bảo trì

# Tối ưu hóa __slots__

  • Dùng các slot cố định thay cho __dict__ để tối ưu bộ nhớ và tốc độ
  • __slots__ sử dụng một tuple chỉ định tên thuộc tính
  • Ngăn việc thêm các thuộc tính không cần thiết vào class
  • Tuy nhiên đây chỉ là mức tối ưu vi mô nên cần cân nhắc khi sử dụng

# Tổng hợp mẹo code style Python

  • Cú pháp for-else: else sẽ chạy nếu vòng lặp kết thúc mà không có break
  • Toán tử walrus (:=): cho phép vừa gán biến vừa kiểm tra
  • Short-circuit với or: trả về giá trị đầu tiên là đúng trong nhiều giá trị
  • Chaining toán tử so sánh: có thể viết gọn như 0 < x < 10

# Định dạng nâng cao với f-string

  • Có thể dùng cú pháp f"{변수=}" để biểu diễn phục vụ debug
  • Hỗ trợ nhiều tùy chọn như định dạng số (:.2f, :+.2f, :,), định dạng ngày (%Y-%m-%d)
  • Có thể tận dụng mini-language định dạng cho căn giữa, padding, biểu diễn phần trăm

# Decorator cache

  • @lru_cache@cache giúp lưu kết quả hàm để cải thiện tốc độ
  • Hữu ích với các hàm đệ quy hoặc các phép tính lặp lại nhiều lần
  • @cache được giới thiệu từ Python 3.9, cung cấp cache mặc định không giới hạn

# Future trong Python

  • đối tượng xử lý bất đồng bộ tương tự Promise trong JS
  • Có thể quản lý kết quả bất đồng bộ bằng Future.set_result(), add_done_callback()
  • asyncio.Future() có thể dùng cùng await
  • Khi dùng với ThreadPoolExecutor, cũng có thể xử lý song song nền

# Thuộc tính proxy (Proxy Property)

  • Cho phép một thuộc tính của class vừa hoạt động như thuộc tính, vừa như hàm
  • Cung cấp hai chức năng này thông qua __get__, __call__, __repr__
  • Khi thiết kế API, có thể xử lý giá trị mặc định và lời gọi có tham số theo một cách thống nhất
  • Dù ít dùng trong thực tế, đây vẫn là một ví dụ thử nghiệm đáng tham khảo

# Metaclass

  • class của class, dùng để tạo ra chính các class
  • Có thể triển khai logic meta như thao tác thuộc tính class hoặc tự động đăng ký
  • Trên thực tế, phần lớn trường hợp có thể thay bằng decorator
  • Trong Django, SQLAlchemy, Pydantic... metaclass vẫn được dùng nội bộ

5 bình luận

 
hackerpropoker 2025-04-29

Từ góc nhìn backend, tôi từng có trải nghiệm rằng metaclass khiến việc gỡ lỗi trở nên khó khăn hơn.

 
ilotoki0804 2025-04-28

Xin lưu ý rằng for-else thường bị xem là anti-pattern vì có ý kiến cho rằng nó không có tính dễ đọc hay rõ ràng cao, và asyncio.Future được coi là chi tiết triển khai nội bộ của asyncio.

 
dkmin 2025-04-26

Cảm ơn. Đặc biệt là mục số 10, tôi sẽ áp dụng ngay.

Thêm quy tắc code AI..

 
yangeok 2025-04-25

Cảm ơn vì mẹo hay.

 
GN⁺ 2025-04-24
Ý kiến trên Hacker News
  • Xin chào! Tôi là tác giả gốc của bài blog này! Tôi đã rất ngạc nhiên khi thấy bài viết của mình lên trang nhất HN lúc 4 giờ sáng

    • Bài này bắt đầu từ 14 tweet nhỏ tôi viết một tháng trước khi bắt đầu blog
    • Khi bắt đầu blog, tôi quyết định tái sử dụng các tweet này làm bài đăng đầu tiên
    • Vì thế nên mạch bài có thể hơi kỳ lạ một chút
    • Tôi cố gắng tìm những thứ hữu ích vào thứ Hai, và những thứ độc đáo hơn vào thứ Sáu
    • Tiêu đề cũng vậy, đây là tập hợp 14 tính năng mà tôi thấy thú vị khi dùng Python
    • Tôi chỉ mất khoảng 5 giây để nghĩ ra tiêu đề
  • Mỗi khi dùng Python, tôi lại lo rằng đoạn mã của mình sẽ trông như đang dùng Python sai cách

    • Tôi ngạc nhiên trước những nội dung chuyên sâu hoặc các thay đổi của Python mà trước đây mình không biết
    • Go mang lại cảm giác yên tâm rằng mã nguồn sẽ không bị lỗi thời sau vài năm
    • Bài viết rất hay
  • Python nên vẫn là Python, còn golang, Rust, Typescript thì mỗi ngôn ngữ nên giữ triết lý và thiết kế riêng của mình

    • Tôi đã lập trình bằng 4 ngôn ngữ suốt 28 năm và không thích những thay đổi của Python
    • Lý do Python trở nên phổ biến không phải là nhờ các lớp bổ sung như kiểm tra kiểu hay chú thích
    • Tôi cũng đã thấy điều tương tự ở các ngôn ngữ khác
    • Đây là một danh sách tổng hợp khá đầy đủ về các tính năng được giới thiệu gần đây
    • Cũng có một danh sách trước đó mà độc giả có thể thấy hữu ích
  • Điểm mạnh lớn nhất của Python là nó tạo cảm giác như mã giả có thể chạy được

    • Ngôn ngữ không cản trở các chỉ thị ở cấp độ miền nghiệp vụ
    • Càng thêm nhiều tính năng thì sức hấp dẫn càng giảm
    • Phần lớn mọi người không thực sự hiểu Python ở mức sâu
  • Góp ý về mục 9.3, phần evaluation: nếu có chuỗi rỗng thì việc đánh giá sẽ diễn ra khác đi

    • Mệnh đề if-else coi chuỗi rỗng là hợp lệ, nhưng toán tử or lại xem nó tương đương với None
  • Là người chuyển từ Javascript/Typescript sang Python, tôi thấy đây là một tài nguyên hữu ích

    • Type overload là để phục vụ một tính năng không mấy hay ho của Javascript, và tôi xem đó là nợ kỹ thuật
    • Đối số chỉ theo từ khóa và chỉ theo vị trí có cú pháp quá cô đọng nên tôi lo về tính dễ đọc
    • Future annotations gần đây đã giúp tôi rất nhiều
    • Protocol giống Typescript nhưng không mang cảm giác đặc trưng của Python
    • Metaclass là công cụ mạnh có thể giải quyết những vấn đề rất riêng
  • Phần lớn các tính năng này không phải là tính năng nâng cao

    • Tôi có xu hướng tránh metaclass vì chúng có thể dẫn đến hành vi phức tạp
    • 'Thuộc tính proxy' không phải là một tính năng
  • Điều tôi muốn thay đổi trong danh sách là việc đưa các container của collections.abc vào

    • Nhiều bình luận không thích toán tử walrus, nhưng sau khi tìm được cách dùng hợp lý thì tôi thấy nó khá hữu ích
    • Khi dùng mẫu biểu thức chính quy, mã trở nên gọn gàng hơn nhiều
  • Tôi rất thích đọc bài này

    • Phần lớn các tính năng là của mô-đun typing
    • Tôi vẫn chưa chắc về generic hay protocol
    • Tôi tò mò liệu mã Python hiện đại ở cấp độ production có dùng type ở khắp nơi hay không