Python hỗ trợ tùy chọn "type hints" (còn được gọi là "type annotations").
Những "type hints" hay chú thích là một cú pháp đặc biệt cho phép khai báo kiểu dữ liệu của một biến.
Bằng việc khai báo kiểu dữ liệu cho các biến của bạn, các trình soạn thảo và các công cụ có thể hỗ trợ bạn tốt hơn.
Đây chỉ là một hướng dẫn nhanh về gợi ý kiểu dữ liệu trong Python. Nó chỉ bao gồm những điều cần thiết tối thiểu để sử dụng chúng với FastAPI... đó thực sự là rất ít.
FastAPI hoàn toàn được dựa trên những gợi ý kiểu dữ liệu, chúng mang đến nhiều ưu điểm và lợi ích.
Nhưng thậm chí nếu bạn không bao giờ sử dụng FastAPI, bạn sẽ được lợi từ việc học một ít về chúng.
Note
Nếu bạn là một chuyên gia về Python, và bạn đã biết mọi thứ về gợi ý kiểu dữ liệu, bỏ qua và đi tới chương tiếp theo.
Các kiểu dữ liệu tổng quát với tham số kiểu dữ liệu¶
Có một vài cấu trúc dữ liệu có thể chứa các giá trị khác nhau như dict, list, set và tuple. Và những giá trị nội tại cũng có thể có kiểu dữ liệu của chúng.
Những kiểu dữ liệu nội bộ này được gọi là những kiểu dữ liệu "tổng quát". Và có khả năng khai báo chúng, thậm chí với các kiểu dữ liệu nội bộ của chúng.
Để khai báo những kiểu dữ liệu và những kiểu dữ liệu nội bộ đó, bạn có thể sử dụng mô đun chuẩn của Python là typing. Nó có hỗ trợ những gợi ý kiểu dữ liệu này.
Cú pháp sử dụng typingtương thích với tất cả các phiên bản, từ Python 3.6 tới những phiên bản cuối cùng, bao gồm Python 3.9, Python 3.10,...
As Python advances, những phiên bản mới mang tới sự hỗ trợ được cải tiến cho những chú thích kiểu dữ liệu và trong nhiều trường hợp bạn thậm chí sẽ không cần import và sử dụng mô đun typing để khai báo chú thích kiểu dữ liệu.
Nếu bạn có thể chọn một phiên bản Python gần đây hơn cho dự án của bạn, ban sẽ có được những ưu điểm của những cải tiến đơn giản đó.
Trong tất cả các tài liệu tồn tại những ví dụ tương thích với mỗi phiên bản Python (khi có một sự khác nhau).
Cho ví dụ "Python 3.6+" có nghĩa là nó tương thích với Python 3.7 hoặc lớn hơn (bao gồm 3.7, 3.8, 3.9, 3.10,...). và "Python 3.9+" nghĩa là nó tương thích với Python 3.9 trở lên (bao gồm 3.10,...).
Nếu bạn có thể sử dụng phiên bản cuối cùng của Python, sử dụng những ví dụ cho phiên bản cuối, những cái đó sẽ có cú pháp đơn giản và tốt nhât, ví dụ, "Python 3.10+".
Sử dụng Optional[str] thay cho str sẽ cho phép trình soạn thảo giúp bạn phát hiện các lỗi mà bạn có thể gặp như một giá trị luôn là một str, trong khi thực tế nó rất có thể là None.
Optional[Something] là một cách viết ngắn gọn của Union[Something, None], chúng là tương đương nhau.
Điều này cũng có nghĩa là trong Python 3.10, bạn có thể sử dụng Something | None:
If you are using a Python version below 3.10, here's a tip from my very subjective point of view:
Nếu bạn đang sử dụng phiên bản Python dưới 3.10, đây là một mẹo từ ý kiến rất "chủ quan" của tôi:
🚨 Tránh sử dụng Optional[SomeType]
Thay vào đó ✨ sử dụng Union[SomeType, None] ✨.
Cả hai là tương đương và bên dưới chúng giống nhau, nhưng tôi sẽ đễ xuất Union thay cho Optional vì từ "tùy chọn" có vẻ ngầm định giá trị là tùy chọn, và nó thực sự có nghĩa rằng "nó có thể là None", do đó nó không phải là tùy chọn và nó vẫn được yêu cầu.
Tôi nghĩ Union[SomeType, None] là rõ ràng hơn về ý nghĩa của nó.
Nó chỉ là về các từ và tên. Nhưng những từ đó có thể ảnh hưởng cách bạn và những đồng đội của bạn suy nghĩ về code.
Tham số name được định nghĩa là Optional[str], nhưng nó không phải là tùy chọn, bạn không thể gọi hàm mà không có tham số:
say_hi()# Oh, no, this throws an error! 😱
Tham số namevẫn được yêu cầu (không phải là tùy chọn) vì nó không có giá trị mặc định. Trong khi đó, name chấp nhận None như là giá trị:
say_hi(name=None)# This works, None is valid 🎉
Tin tốt là, khi bạn sử dụng Python 3.10, bạn sẽ không phải lo lắng về điều đó, bạn sẽ có thể sử dụng | để định nghĩa hợp của các kiểu dữ liệu một cách đơn giản:
defsay_hi(name:str|None):print(f"Hey {name}!")
Và sau đó, bạn sẽ không phải lo rằng những cái tên như Optional và Union. 😎
Những kiểu dữ liệu này lấy tham số kiểu dữ liệu trong dấu ngoặc vuông được gọi là Kiểu dữ liệu tổng quát, cho ví dụ:
Bạn có thể sử dụng các kiểu dữ liệu có sẵn như là kiểu dữ liệu tổng quát (với ngoặc vuông và kiểu dữ liệu bên trong):
list
tuple
set
dict
Và tương tự với Python 3.6, từ mô đun typing:
Union
Optional (tương tự như Python 3.6)
...và các kiểu dữ liệu khác.
Trong Python 3.10, thay vì sử dụng Union và Optional, bạn có thể sử dụng sổ dọc ('|') để khai báo hợp của các kiểu dữ liệu, điều đó tốt hơn và đơn giản hơn nhiều.
Bạn có thể sử dụng các kiểu dữ liệu có sẵn tương tự như (với ngoặc vuông và kiểu dữ liệu bên trong):
Pydantic là một thư viện Python để validate dữ liệu hiệu năng cao.
Bạn có thể khai báo "hình dạng" của dữa liệu như là các lớp với các thuộc tính.
Và mỗi thuộc tính có một kiểu dữ liệu.
Sau đó bạn tạo một thực thể của lớp đó với một vài giá trị và nó sẽ validate các giá trị, chuyển đổi chúng sang kiểu dữ liệu phù hợp (nếu đó là trường hợp) và cho bạn một object với toàn bộ dữ liệu.
Và bạn nhận được tất cả sự hỗ trợ của trình soạn thảo với object kết quả đó.
Pydantic có một hành vi đặc biệt khi bạn sử dụng Optional hoặc Union[Something, None] mà không có giá trị mặc dịnh, bạn có thể đọc nhiều hơn về nó trong tài liệu của Pydantic về Required Optional fields.
Python cũng có một tính năng cho phép đặt metadata bổ sung trong những gợi ý kiểu dữ liệu này bằng cách sử dụng Annotated.
Trong Python 3.9, Annotated là một phần của thư viện chuẩn, do đó bạn có thể import nó từ typing.
fromtypingimportAnnotateddefsay_hello(name:Annotated[str,"this is just metadata"])->str:returnf"Hello {name}"
Ở phiên bản dưới Python 3.9, bạn import Annotated từ typing_extensions.
Nó đã được cài đặt sẵng cùng với FastAPI.
fromtyping_extensionsimportAnnotateddefsay_hello(name:Annotated[str,"this is just metadata"])->str:returnf"Hello {name}"
Python bản thân nó không làm bất kì điều gì với Annotated. Với các trình soạn thảo và các công cụ khác, kiểu dữ liệu vẫn là str.
Nhưng bạn có thể sử dụng Annotated để cung cấp cho FastAPI metadata bổ sung về cách mà bạn muốn ứng dụng của bạn xử lí.
Điều quan trọng cần nhớ là tham số kiểu dữ liệu đầu tiên bạn truyền tới Annotated là kiểu giá trị thực sự. Phần còn lại chỉ là metadata cho các công cụ khác.
Bây giờ, bạn chỉ cần biết rằng Annotated tồn tại, và nó là tiêu chuẩn của Python. 😎
Sau đó, bạn sẽ thấy sự mạnh mẽ mà nó có thể làm.
Tip
Thực tế, cái này là tiêu chuẩn của Python, nghĩa là bạn vẫn sẽ có được trải nghiệm phát triển tốt nhất có thể với trình soạn thảo của bạn, với các công cụ bạn sử dụng để phân tích và tái cấu trúc code của bạn, etc. ✨
Và code của bạn sẽ tương thích với nhiều công cụ và thư viện khác của Python. 🚀
FastAPI lấy các ưu điểm của các gợi ý kiểu dữ liệu để thực hiện một số thứ.
Với FastAPI, bạn khai báo các tham số với gợi ý kiểu và bạn có được:
Sự hỗ trợ từ các trình soạn thảo.
Kiểm tra kiểu dữ liệu (type checking).
...và FastAPI sử dụng các khia báo để:
Định nghĩa các yêu cầu: từ tham số đường dẫn của request, tham số query, headers, bodies, các phụ thuộc (dependencies),...
*Chuyển dổi dữ liệu: từ request sang kiểu dữ liệu được yêu cầu.
Kiểm tra tính đúng đắn của dữ liệu: tới từ mỗi request:
Sinh lỗi tự động để trả về máy khác khi dữ liệu không hợp lệ.
Tài liệu hóa API sử dụng OpenAPI:
cái mà sau được được sử dụng bởi tài liệu tương tác người dùng.
Điều này có thể nghe trừu tượng. Đừng lo lắng. Bạn sẽ thấy tất cả chúng trong Hướng dẫn sử dụng.
Điều quan trọng là bằng việc sử dụng các kiểu dữ liệu chuẩn của Python (thay vì thêm các lớp, decorators,...), FastAPI sẽ thực hiện nhiều công việc cho bạn.
Info
Nếu bạn đã đi qua toàn bộ các hướng dẫn và quay trở lại để tìm hiểu nhiều hơn về các kiểu dữ liệu, một tài nguyên tốt như "cheat sheet" từ mypy.