Các câu trả lời khác đã làm rất tốt trong việc giải thích cách gõ vịt và câu trả lời đơn giản của tzot :
Python không có biến, giống như các ngôn ngữ khác trong đó các biến có loại và giá trị; Nó có tên chỉ vào các đối tượng, biết loại của chúng.
Tuy nhiên , một điều thú vị đã thay đổi kể từ năm 2010 (khi câu hỏi được đặt ra lần đầu tiên), đó là việc triển khai PEP 3107 (được triển khai trong Python 3). Bây giờ bạn thực sự có thể chỉ định loại tham số và loại trả về của hàm như thế này:
def pick(l: list, index: int) -> int:
return l[index]
Ở đây chúng ta có thể thấy rằng pick
có 2 tham số, một danh sách l
và một số nguyên index
. Nó cũng sẽ trả về một số nguyên.
Vì vậy, ở đây có ngụ ý rằng đó l
là một danh sách các số nguyên mà chúng ta có thể thấy mà không cần nỗ lực nhiều, nhưng đối với các hàm phức tạp hơn, có thể hơi khó hiểu về danh sách nên chứa. Chúng tôi cũng muốn giá trị mặc định index
là 0. Để giải quyết điều này, bạn có thể chọn viết pick
như thế này:
def pick(l: "list of ints", index: int = 0) -> int:
return l[index]
Lưu ý rằng bây giờ chúng ta đặt một chuỗi là loại l
, được phép theo cú pháp, nhưng nó không tốt cho việc phân tích cú pháp theo chương trình (mà chúng ta sẽ quay lại sau).
Điều quan trọng cần lưu ý là Python sẽ không nâng cao TypeError
nếu bạn vượt qua index
, lý do cho điều này là một trong những điểm chính trong triết lý thiết kế của Python: "Tất cả chúng ta đều đồng ý ở đây" , có nghĩa là bạn được mong đợi lưu ý về những gì bạn có thể chuyển đến một chức năng và những gì bạn không thể. Nếu bạn thực sự muốn viết mã ném TypeErrors, bạn có thể sử dụng isinstance
hàm để kiểm tra xem đối số được truyền có thuộc loại thích hợp hay một lớp con của nó như thế này không:
def pick(l: list, index: int = 0) -> int:
if not isinstance(l, list):
raise TypeError
return l[index]
Thông tin thêm về lý do tại sao bạn hiếm khi nên làm điều này và những gì bạn nên làm thay vào đó được nói đến trong phần tiếp theo và trong các bình luận.
PEP 3107 không chỉ cải thiện khả năng đọc mã mà còn có một số trường hợp sử dụng phù hợp mà bạn có thể đọc về đây .
Chú thích kiểu đã thu hút sự chú ý nhiều hơn trong Python 3.5 với việc giới thiệu PEP 484 , giới thiệu một mô-đun chuẩn cho gợi ý về kiểu.
Những gợi ý loại này đến từ trình kiểm tra loại mypy ( GitHub ), hiện đang tuân thủ PEP 484 .
Với mô-đun gõ đi kèm với một bộ sưu tập gợi ý khá toàn diện, bao gồm:
List
, Tuple
, Set
, Map
- cho list
, tuple
, set
và map
tương ứng.
Iterable
- hữu ích cho máy phát điện.
Any
- khi nó có thể là bất cứ điều gì.
Union
- khi nó có thể là bất cứ thứ gì trong một tập hợp các loại được chỉ định, trái ngược với Any
.
Optional
- khi nó có thể là Không có. Viết tắt cho Union[T, None]
.
TypeVar
- được sử dụng với thuốc generic.
Callable
- được sử dụng chủ yếu cho các chức năng, nhưng có thể được sử dụng cho các tên gọi khác.
Đây là những gợi ý loại phổ biến nhất. Một danh sách đầy đủ có thể được tìm thấy trong tài liệu cho mô-đun gõ .
Dưới đây là ví dụ cũ sử dụng các phương thức chú thích được giới thiệu trong mô-đun gõ:
from typing import List
def pick(l: List[int], index: int) -> int:
return l[index]
Một tính năng mạnh mẽ là Callable
cho phép bạn nhập các phương thức chú thích lấy một hàm làm đối số. Ví dụ:
from typing import Callable, Any, Iterable
def imap(f: Callable[[Any], Any], l: Iterable[Any]) -> List[Any]:
"""An immediate version of map, don't pass it any infinite iterables!"""
return list(map(f, l))
Ví dụ trên có thể trở nên chính xác hơn với việc sử dụng TypeVar
thay vì Any
, nhưng điều này đã được để lại cho người đọc vì tôi tin rằng tôi đã điền vào câu trả lời của mình với quá nhiều thông tin về các tính năng mới tuyệt vời được kích hoạt bằng cách gõ gợi ý.
Trước đây khi một tài liệu mã Python với Sphinx, ví dụ, một số chức năng trên có thể có được bằng cách viết các tài liệu được định dạng như sau:
def pick(l, index):
"""
:param l: list of integers
:type l: list
:param index: index at which to pick an integer from *l*
:type index: int
:returns: integer at *index* in *l*
:rtype: int
"""
return l[index]
Như bạn có thể thấy, điều này cần một số dòng bổ sung (số chính xác phụ thuộc vào mức độ rõ ràng bạn muốn và cách bạn định dạng chuỗi tài liệu của mình). Nhưng bây giờ bạn cần phải rõ ràng về cách PEP 3107 cung cấp một giải pháp thay thế vượt trội hơn nhiều (tất cả?). Điều này đặc biệt đúng khi kết hợp với PEP 484 , như chúng ta đã thấy, cung cấp một mô-đun chuẩn xác định cú pháp cho các gợi ý / chú thích loại này có thể được sử dụng theo cách rõ ràng và chính xác nhưng linh hoạt, tạo ra một sự kết hợp mạnh mẽ.
Theo ý kiến cá nhân của tôi, đây là một trong những tính năng tuyệt vời nhất trong Python từ trước đến nay. Tôi không thể chờ đợi mọi người bắt đầu khai thác sức mạnh của nó. Xin lỗi vì câu trả lời dài, nhưng đây là những gì xảy ra khi tôi cảm thấy phấn khích.
Một ví dụ về mã Python sử dụng nhiều gợi ý kiểu có thể được tìm thấy ở đây .