PEP 3107 đã giới thiệu cú pháp cho các chú thích hàm, nhưng ngữ nghĩa không được xác định một cách có chủ ý. Hiện tại đã có đủ cách sử dụng của bên thứ 3 để phân tích kiểu tĩnh mà cộng đồng sẽ được hưởng lợi từ vốn từ vựng tiêu chuẩn và các công cụ cơ bản trong thư viện tiêu chuẩn
PEP này giới thiệu một mô-đun tạm thời để cung cấp các định nghĩa và công cụ tiêu chuẩn này, cùng với một số quy ước cho các tình huống không có chú thích
Lưu ý rằng PEP này rõ ràng vẫn KHÔNG ngăn cản việc sử dụng các chú thích khác, cũng như không yêu cầu [hoặc cấm] bất kỳ quá trình xử lý chú thích cụ thể nào, ngay cả khi chúng tuân theo thông số kỹ thuật này. Nó chỉ đơn giản là cho phép phối hợp tốt hơn, như PEP 333 đã làm cho các khung web
Ví dụ, đây là một hàm đơn giản có đối số và kiểu trả về được khai báo trong chú thích
def greeting[name: str] -> str: return 'Hello ' + name
Mặc dù các chú thích này có sẵn trong thời gian chạy thông qua thuộc tính
def greeting[name: str] -> str: return 'Hello ' + name15 thông thường, không có kiểm tra loại nào xảy ra trong thời gian chạy. Thay vào đó, đề xuất giả định sự tồn tại của một trình kiểm tra loại ngoại tuyến riêng biệt mà người dùng có thể tự nguyện chạy qua mã nguồn của họ. Về cơ bản, một trình kiểm tra loại như vậy hoạt động như một kẻ nói dối rất mạnh mẽ. [Mặc dù người dùng cá nhân có thể sử dụng một trình kiểm tra tương tự trong thời gian chạy để thực thi Thiết kế theo hợp đồng hoặc tối ưu hóa JIT, nhưng những công cụ đó vẫn chưa hoàn thiện. ]
Đề xuất được truyền cảm hứng mạnh mẽ bởi mypy. Ví dụ: kiểu “dãy số nguyên” có thể được viết là
def greeting[name: str] -> str: return 'Hello ' + name16. Dấu ngoặc vuông có nghĩa là không cần thêm cú pháp mới vào ngôn ngữ. Ví dụ ở đây sử dụng loại tùy chỉnh
def greeting[name: str] -> str: return 'Hello ' + name17, được nhập từ mô-đun Python thuần túy
def greeting[name: str] -> str: return 'Hello ' + name14. Ký hiệu
def greeting[name: str] -> str: return 'Hello ' + name16 hoạt động trong thời gian chạy bằng cách triển khai
def greeting[name: str] -> str: return 'Hello ' + name20 trong siêu dữ liệu [nhưng ý nghĩa của nó chủ yếu là đối với trình kiểm tra loại ngoại tuyến]
Hệ thống loại hỗ trợ các loại hợp nhất, loại chung và loại đặc biệt có tên
def greeting[name: str] -> str: return 'Hello ' + name12 phù hợp với [i. e. có thể gán cho và từ] tất cả các loại. Tính năng thứ hai này được lấy từ ý tưởng gõ dần dần. Đánh máy dần dần và hệ thống đánh máy đầy đủ được giải thích trong PEP 483
Các cách tiếp cận khác mà chúng tôi đã vay mượn hoặc các cách tiếp cận của chúng tôi có thể được so sánh và đối chiếu được mô tả trong PEP 482
PEP 3107 đã thêm hỗ trợ cho các chú thích tùy ý trên các phần của định nghĩa hàm. Mặc dù sau đó không có ý nghĩa nào được gán cho các chú thích, nhưng luôn có một mục tiêu ngầm định để sử dụng chúng cho gợi ý loại, được liệt kê là trường hợp sử dụng đầu tiên có thể có trong PEP đã nói
PEP này nhằm mục đích cung cấp một cú pháp tiêu chuẩn cho các chú thích kiểu, mở mã Python để phân tích và tái cấu trúc tĩnh dễ dàng hơn, kiểm tra kiểu thời gian chạy tiềm năng và [có lẽ, trong một số ngữ cảnh] tạo mã sử dụng thông tin kiểu
Trong số các mục tiêu này, phân tích tĩnh là quan trọng nhất. Điều này bao gồm hỗ trợ cho các trình kiểm tra loại ngoại tuyến như mypy, cũng như cung cấp một ký hiệu chuẩn mà các IDE có thể sử dụng để hoàn thành và tái cấu trúc mã
Mặc dù mô-đun nhập liệu được đề xuất sẽ chứa một số khối xây dựng để kiểm tra loại thời gian chạy – cụ thể là hàm
def greeting[name: str] -> str: return 'Hello ' + name22 – các gói của bên thứ ba sẽ phải được phát triển để triển khai chức năng kiểm tra loại thời gian chạy cụ thể, ví dụ như sử dụng trình trang trí hoặc siêu dữ liệu. Sử dụng gợi ý loại để tối ưu hóa hiệu suất được để lại như một bài tập cho người đọc
Cũng cần nhấn mạnh rằng Python sẽ vẫn là một ngôn ngữ được gõ động và các tác giả không muốn đưa ra các gợi ý kiểu bắt buộc, thậm chí theo quy ước
Bất kỳ chức năng nào không có chú thích phải được coi là có loại chung nhất có thể hoặc bị bỏ qua bởi bất kỳ trình kiểm tra loại nào. Các chức năng với trình trang trí
def greeting[name: str] -> str: return 'Hello ' + name23 nên được coi là không có chú thích
Các hàm được kiểm tra được khuyến nghị nhưng không bắt buộc phải có chú thích cho tất cả các đối số và kiểu trả về. Đối với một hàm được kiểm tra, chú thích mặc định cho các đối số và cho kiểu trả về là
def greeting[name: str] -> str: return 'Hello ' + name12. Một ngoại lệ là đối số đầu tiên của các phương thức thể hiện và lớp. Nếu nó không được chú thích, thì nó được giả định là có kiểu của lớp chứa đối với các phương thức thể hiện và một kiểu đối tượng kiểu tương ứng với đối tượng lớp chứa đối với các phương thức lớp. Ví dụ, trong lớp
def greeting[name: str] -> str: return 'Hello ' + name25, đối số đầu tiên của một phương thức thể hiện có kiểu ngầm định là
def greeting[name: str] -> str: return 'Hello ' + name25. In a class method, the precise type of the first argument cannot be represented using the available type notation
[Note that the return type of
def greeting[name: str] -> str: return 'Hello ' + name27 ought to be annotated with
def greeting[name: str] -> str: return 'Hello ' + name28. The reason for this is subtle. If
def greeting[name: str] -> str: return 'Hello ' + name27 assumed a return annotation of
def greeting[name: str] -> str: return 'Hello ' + name28, would that mean that an argument-less, un-annotated
def greeting[name: str] -> str: return 'Hello ' + name27 method should still be type-checked? Rather than leaving this ambiguous or introducing an exception to the exception, we simply say that
def greeting[name: str] -> str: return 'Hello ' + name27 ought to have a return annotation; the default behavior is thus the same as for other methods. ]
A type checker is expected to check the body of a checked function for consistency with the given annotations. The annotations may also be used to check correctness of calls appearing in other checked functions
Type checkers are expected to attempt to infer as much information as necessary. The minimum requirement is to handle the builtin decorators
def greeting[name: str] -> str: return 'Hello ' + name33,
def greeting[name: str] -> str: return 'Hello ' + name34 and
def greeting[name: str] -> str: return 'Hello ' + name35
The syntax leverages PEP 3107-style annotations with a number of extensions described in sections below. In its basic form, type hinting is used by filling function annotation slots with classes
def greeting[name: str] -> str: return 'Hello ' + name
This states that the expected type of the
def greeting[name: str] -> str: return 'Hello ' + name36 argument is
def greeting[name: str] -> str: return 'Hello ' + name37. Analogically, the expected return type is
def greeting[name: str] -> str: return 'Hello ' + name37
Expressions whose type is a subtype of a specific argument type are also accepted for that argument
Type hints may be built-in classes [including those defined in standard library or third-party extension modules], abstract base classes, types available in the
def greeting[name: str] -> str: return 'Hello ' + name39 module, and user-defined classes [including those defined in the standard library or third-party modules]
While annotations are normally the best format for type hints, there are times when it is more appropriate to represent them by a special comment, or in a separately distributed stub file. [See below for examples. ]
Annotations must be valid expressions that evaluate without raising exceptions at the time the function is defined [but see below for forward references]
Annotations should be kept simple or static analysis tools may not be able to interpret the values. For example, dynamically computed types are unlikely to be understood. [This is an intentionally somewhat vague requirement, specific inclusions and exclusions may be added to future versions of this PEP as warranted by the discussion. ]
In addition to the above, the following special constructs defined below may be used.
def greeting[name: str] -> str: return 'Hello ' + name40,
def greeting[name: str] -> str: return 'Hello ' + name12,
def greeting[name: str] -> str: return 'Hello ' + name42,
def greeting[name: str] -> str: return 'Hello ' + name43,
def greeting[name: str] -> str: return 'Hello ' + name44, all ABCs and stand-ins for concrete classes exported from
def greeting[name: str] -> str: return 'Hello ' + name14 [e. g.
def greeting[name: str] -> str: return 'Hello ' + name17 and
def greeting[name: str] -> str: return 'Hello ' + name47], type variables, and type aliases
All newly introduced names used to support features described in following sections [such as
def greeting[name: str] -> str: return 'Hello ' + name12 and
def greeting[name: str] -> str: return 'Hello ' + name42] are available in the
def greeting[name: str] -> str: return 'Hello ' + name14 module
When used in a type hint, the expression
def greeting[name: str] -> str: return 'Hello ' + name40 is considered equivalent to
def greeting[name: str] -> str: return 'Hello ' + name52
Type aliases are defined by simple variable assignments
Url = str def retry[url: Url, retry_count: int] -> None: ...
Note that we recommend capitalizing alias names, since they represent user-defined types, which [like user-defined classes] are typically spelled that way
Type aliases may be as complex as type hints in annotations – anything that is acceptable as a type hint is acceptable in a type alias
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]
Điều này tương đương với
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
Frameworks expecting callback functions of specific signatures might be type hinted using
def greeting[name: str] -> str: return 'Hello ' + name53. Examples
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
It is possible to declare the return type of a callable without specifying the call signature by substituting a literal ellipsis [three dots] for the list of arguments
def partial[func: Callable[..., str], *args] -> Callable[..., str]: # Body
Note that there are no square brackets around the ellipsis. The arguments of the callback are completely unconstrained in this case [and keyword arguments are acceptable]
Since using callbacks with keyword arguments is not perceived as a common use case, there is currently no support for specifying keyword arguments with
def greeting[name: str] -> str: return 'Hello ' + name44. Similarly, there is no support for specifying callback signatures with a variable number of arguments of a specific type
Because
def greeting[name: str] -> str: return 'Hello ' + name55 does double-duty as a replacement for
def greeting[name: str] -> str: return 'Hello ' + name56,
def greeting[name: str] -> str: return 'Hello ' + name57 is implemented by deferring to
def greeting[name: str] -> str: return 'Hello ' + name58. However,
def greeting[name: str] -> str: return 'Hello ' + name59 is not supported
Since type information about objects kept in containers cannot be statically inferred in a generic way, abstract base classes have been extended to support subscription to denote expected types for container elements. Example
from typing import Mapping, Set def notify_by_email[employees: Set[Employee], overrides: Mapping[str, str]] -> None: ...
Generics can be parameterized by using a new factory available in
def greeting[name: str] -> str: return 'Hello ' + name14 called
def greeting[name: str] -> str: return 'Hello ' + name61. Example
from typing import Sequence, TypeVar T = TypeVar['T'] # Declare type variable def first[l: Sequence[T]] -> T: # Generic function return l[0]
In this case the contract is that the returned value is consistent with the elements held by the collection
Biểu thức
def greeting[name: str] -> str: return 'Hello ' + name62 phải luôn được gán trực tiếp cho một biến [không nên sử dụng biểu thức này như một phần của biểu thức lớn hơn]. Đối số của
def greeting[name: str] -> str: return 'Hello ' + name62 phải là một chuỗi bằng với tên biến mà nó được gán. Các biến loại không được xác định lại
def greeting[name: str] -> str: return 'Hello ' + name61 hỗ trợ ràng buộc các loại tham số thành một tập cố định các loại có thể [lưu ý. những loại đó không thể được tham số hóa bởi các biến loại]. Ví dụ: chúng ta có thể định nghĩa một biến loại chỉ nằm trong phạm vi của
def greeting[name: str] -> str: return 'Hello ' + name37 và
def greeting[name: str] -> str: return 'Hello ' + name66. Theo mặc định, một biến loại bao gồm tất cả các loại có thể. Ví dụ về ràng buộc một biến kiểu
from typing import TypeVar, Text AnyStr = TypeVar['AnyStr', Text, bytes] def concat[x: AnyStr, y: AnyStr] -> AnyStr: return x + y
Hàm
def greeting[name: str] -> str: return 'Hello ' + name67 có thể được gọi với hai đối số
def greeting[name: str] -> str: return 'Hello ' + name37 hoặc hai đối số
def greeting[name: str] -> str: return 'Hello ' + name66, nhưng không được gọi với sự kết hợp của các đối số
def greeting[name: str] -> str: return 'Hello ' + name37 và ________0____66
Nên có ít nhất hai ràng buộc, nếu có;
Các kiểu con của các kiểu bị hạn chế bởi một biến kiểu nên được coi là các kiểu cơ sở được liệt kê rõ ràng tương ứng của chúng trong ngữ cảnh của biến kiểu. Hãy xem xét ví dụ này
def greeting[name: str] -> str: return 'Hello ' + name0
Cuộc gọi hợp lệ nhưng biến loại
def greeting[name: str] -> str: return 'Hello ' + name72 sẽ được đặt thành
def greeting[name: str] -> str: return 'Hello ' + name37 chứ không phải
def greeting[name: str] -> str: return 'Hello ' + name74. Trên thực tế, loại suy luận của giá trị trả về được gán cho
def greeting[name: str] -> str: return 'Hello ' + name75 cũng sẽ là
def greeting[name: str] -> str: return 'Hello ' + name37
Ngoài ra,
def greeting[name: str] -> str: return 'Hello ' + name12 là một giá trị hợp lệ cho mọi biến loại. Hãy xem xét những điều sau đây
def greeting[name: str] -> str: return 'Hello ' + name1
Điều này tương đương với việc bỏ qua ký hiệu chung và chỉ nói
def greeting[name: str] -> str: return 'Hello ' + name78
Bạn có thể bao gồm một lớp cơ sở
def greeting[name: str] -> str: return 'Hello ' + name79 để định nghĩa một lớp do người dùng định nghĩa là chung chung. Thí dụ
def greeting[name: str] -> str: return 'Hello ' + name2
def greeting[name: str] -> str: return 'Hello ' + name80 làm lớp cơ sở định nghĩa rằng lớp
def greeting[name: str] -> str: return 'Hello ' + name81 nhận một tham số kiểu duy nhất là
def greeting[name: str] -> str: return 'Hello ' + name82. Điều này cũng làm cho
def greeting[name: str] -> str: return 'Hello ' + name82 hợp lệ như một loại trong nội dung lớp
Lớp cơ sở
def greeting[name: str] -> str: return 'Hello ' + name79 sử dụng một siêu dữ liệu xác định
def greeting[name: str] -> str: return 'Hello ' + name85 để
def greeting[name: str] -> str: return 'Hello ' + name86 hợp lệ như một loại
def greeting[name: str] -> str: return 'Hello ' + name3
Một loại chung có thể có bất kỳ số lượng biến loại nào và các biến loại có thể bị hạn chế. This is valid
def greeting[name: str] -> str: return 'Hello ' + name4
Mỗi đối số biến loại cho
def greeting[name: str] -> str: return 'Hello ' + name79 phải khác biệt. Điều này là không hợp lệ
def greeting[name: str] -> str: return 'Hello ' + name5
Lớp cơ sở
def greeting[name: str] -> str: return 'Hello ' + name80 là dư thừa trong các trường hợp đơn giản khi bạn phân lớp một số lớp chung khác và chỉ định các biến kiểu cho các tham số của nó
def greeting[name: str] -> str: return 'Hello ' + name6
Định nghĩa lớp đó tương đương với
def greeting[name: str] -> str: return 'Hello ' + name7
Bạn có thể sử dụng đa thừa kế với
def greeting[name: str] -> str: return 'Hello ' + name79
def greeting[name: str] -> str: return 'Hello ' + name8
Phân lớp một lớp chung mà không chỉ định tham số loại giả định ____0_______12 cho mỗi vị trí. Trong ví dụ sau,
def greeting[name: str] -> str: return 'Hello ' + name91 không phải là chung chung nhưng hoàn toàn kế thừa từ
def greeting[name: str] -> str: return 'Hello ' + name92
def greeting[name: str] -> str: return 'Hello ' + name9
Siêu dữ liệu chung không được hỗ trợ
Loại biến tuân theo quy tắc phân giải tên thông thường. Tuy nhiên, có một số trường hợp đặc biệt trong ngữ cảnh kiểm tra đánh máy tĩnh
- Một biến loại được sử dụng trong một hàm chung có thể được suy ra để đại diện cho các loại khác nhau trong cùng một khối mã. Thí dụ
Url = str def retry[url: Url, retry_count: int] -> None: ...
0 - Biến kiểu được sử dụng trong phương thức của lớp chung trùng với một trong các biến tham số hóa lớp này luôn được liên kết với biến đó. Thí dụ
Url = str def retry[url: Url, retry_count: int] -> None: ...
1 - Một biến loại được sử dụng trong một phương thức không khớp với bất kỳ biến nào tham số hóa lớp làm cho phương thức này trở thành một hàm chung trong biến đó
Url = str def retry[url: Url, retry_count: int] -> None: ...
2 - Các biến loại không liên kết sẽ không xuất hiện trong phần thân của các hàm chung hoặc trong phần thân của lớp ngoài các định nghĩa phương thức
Url = str def retry[url: Url, retry_count: int] -> None: ...
3 - Một định nghĩa lớp chung xuất hiện bên trong một hàm chung không nên sử dụng các biến kiểu tham số hóa hàm chung
Url = str def retry[url: Url, retry_count: int] -> None: ...
4 - Một lớp chung được lồng trong một lớp chung khác không thể sử dụng các biến cùng loại. Phạm vi của các biến kiểu của lớp bên ngoài không bao gồm lớp bên trong
Url = str def retry[url: Url, retry_count: int] -> None: ...
5
Các lớp chung do người dùng định nghĩa có thể được khởi tạo. Giả sử chúng ta viết một lớp
def greeting[name: str] -> str: return 'Hello ' + name93 kế thừa từ
def greeting[name: str] -> str: return 'Hello ' + name80
Url = str def retry[url: Url, retry_count: int] -> None: ...6
Để tạo các phiên bản
def greeting[name: str] -> str: return 'Hello ' + name93, bạn gọi
def greeting[name: str] -> str: return 'Hello ' + name96 giống như đối với một lớp thông thường. Trong thời gian chạy, loại [lớp] của thể hiện sẽ là
def greeting[name: str] -> str: return 'Hello ' + name93. Nhưng loại nào nó phải kiểm tra loại? . Nếu hàm tạo [_______0_______27 hoặc
def greeting[name: str] -> str: return 'Hello ' + name99] sử dụng
def greeting[name: str] -> str: return 'Hello ' + name82 trong chữ ký của nó và một giá trị đối số tương ứng được truyền vào, loại của [các] đối số tương ứng sẽ được thay thế. Mặt khác,
def greeting[name: str] -> str: return 'Hello ' + name12 được giả định. Thí dụ
Url = str def retry[url: Url, retry_count: int] -> None: ...7
Trong trường hợp loại được suy luận sử dụng
Url = str def retry[url: Url, retry_count: int] -> None: ...02 nhưng loại dự định cụ thể hơn, bạn có thể sử dụng nhận xét loại [xem bên dưới] để buộc loại biến, e. g
Url = str def retry[url: Url, retry_count: int] -> None: ...8
Ngoài ra, bạn có thể khởi tạo một loại bê tông cụ thể, e. g
Url = str def retry[url: Url, retry_count: int] -> None: ...9
Lưu ý rằng loại [lớp] thời gian chạy của
Url = str def retry[url: Url, retry_count: int] -> None: ...03 và
Url = str def retry[url: Url, retry_count: int] -> None: ...04 vẫn chỉ là
def greeting[name: str] -> str: return 'Hello ' + name93 –
Url = str def retry[url: Url, retry_count: int] -> None: ...06 và
Url = str def retry[url: Url, retry_count: int] -> None: ...07 là các đối tượng lớp có thể phân biệt được, nhưng lớp thời gian chạy của các đối tượng được tạo bằng cách khởi tạo chúng không ghi lại sự khác biệt. Hành vi này được gọi là "loại xóa"; . g. Java, TypeScript]
Sử dụng các lớp chung [được tham số hóa hoặc không] để truy cập các thuộc tính sẽ dẫn đến lỗi kiểm tra kiểu. Bên ngoài phần định nghĩa lớp, thuộc tính lớp không thể được chỉ định và chỉ có thể được tra cứu bằng cách truy cập nó thông qua một thể hiện của lớp không có thuộc tính thể hiện có cùng tên
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]0
Các phiên bản chung của các tập hợp trừu tượng như
Url = str def retry[url: Url, retry_count: int] -> None: ...08 hoặc
def greeting[name: str] -> str: return 'Hello ' + name17 và các phiên bản chung của các lớp dựng sẵn –
Url = str def retry[url: Url, retry_count: int] -> None: ...10,
def greeting[name: str] -> str: return 'Hello ' + name47,
Url = str def retry[url: Url, retry_count: int] -> None: ...12 và
Url = str def retry[url: Url, retry_count: int] -> None: ...13 – không thể được khởi tạo. Tuy nhiên, các lớp con cụ thể do người dùng định nghĩa và các phiên bản chung của các bộ sưu tập cụ thể có thể được khởi tạo
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]1
Lưu ý rằng không nên nhầm lẫn giữa các loại tĩnh và các lớp thời gian chạy. Loại vẫn bị xóa trong trường hợp này và biểu thức trên chỉ là cách viết tắt của
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]2
Không nên sử dụng lớp được chỉ định [e. g.
Url = str def retry[url: Url, retry_count: int] -> None: ...06] trực tiếp trong một biểu thức – sử dụng bí danh loại [e. g.
Url = str def retry[url: Url, retry_count: int] -> None: ...15] thay vào đó được ưu tiên. [Đầu tiên, tạo lớp có chỉ số, e. g.
Url = str def retry[url: Url, retry_count: int] -> None: ...06, có chi phí thời gian chạy. Thứ hai, sử dụng bí danh loại dễ đọc hơn. ]
def greeting[name: str] -> str: return 'Hello ' + name80 chỉ có giá trị như một lớp cơ sở – nó không phải là một loại thích hợp. Tuy nhiên, các loại chung do người dùng xác định, chẳng hạn như
Url = str def retry[url: Url, retry_count: int] -> None: ...18 từ ví dụ trên và các loại chung và ABC tích hợp sẵn, chẳng hạn như
Url = str def retry[url: Url, retry_count: int] -> None: ...19 và
Url = str def retry[url: Url, retry_count: int] -> None: ...20 đều hợp lệ cả dưới dạng loại và dưới dạng lớp cơ sở. Ví dụ: chúng ta có thể định nghĩa một lớp con của
def greeting[name: str] -> str: return 'Hello ' + name47 chuyên về các đối số kiểu
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]3
Url = str def retry[url: Url, retry_count: int] -> None: ...22 là lớp con của
Url = str def retry[url: Url, retry_count: int] -> None: ...23 và là lớp con của
Url = str def retry[url: Url, retry_count: int] -> None: ...24
Nếu một lớp cơ sở chung có một biến kiểu làm đối số kiểu, thì điều này làm cho lớp đã định nghĩa trở nên chung. Ví dụ: chúng ta có thể định nghĩa một lớp
Url = str def retry[url: Url, retry_count: int] -> None: ...25 chung có thể lặp lại và một bộ chứa
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]4
Bây giờ
Url = str def retry[url: Url, retry_count: int] -> None: ...26 là một loại hợp lệ. Note that we can use
def greeting[name: str] -> str: return 'Hello ' + name82 multiple times in the base class list, as long as we don’t use the same type variable
def greeting[name: str] -> str: return 'Hello ' + name82 multiple times within
Url = str def retry[url: Url, retry_count: int] -> None: ...29
Cũng xem xét ví dụ sau
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]5
Trong trường hợp này MyDict có một tham số duy nhất, T
Siêu lớp được sử dụng bởi
def greeting[name: str] -> str: return 'Hello ' + name79 là một lớp con của
Url = str def retry[url: Url, retry_count: int] -> None: ...31. Một lớp chung có thể là một ABC bằng cách bao gồm các phương thức hoặc thuộc tính trừu tượng và các lớp chung cũng có thể có ABC làm lớp cơ sở mà không có xung đột siêu dữ liệu
A type variable may specify an upper bound using
Url = str def retry[url: Url, retry_count: int] -> None: ...32 [note: itself cannot be parameterized by type variables]. This means that an actual type substituted [explicitly or implicitly] for the type variable must be a subtype of the boundary type. Example:
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]6
Không thể kết hợp giới hạn trên với các ràng buộc kiểu [như trong
def greeting[name: str] -> str: return 'Hello ' + name72 được sử dụng, xem ví dụ trước đó];
Xét một lớp
Url = str def retry[url: Url, retry_count: int] -> None: ...34 với một lớp con
Url = str def retry[url: Url, retry_count: int] -> None: ...35. Bây giờ, giả sử chúng ta có một hàm với một đối số được chú thích bằng
Url = str def retry[url: Url, retry_count: int] -> None: ...36. Chúng ta có được phép gọi hàm này với một biến kiểu
Url = str def retry[url: Url, retry_count: int] -> None: ...37 làm đối số của nó không? . Nhưng trừ khi chúng ta biết nhiều hơn về chức năng này, bộ kiểm tra kiểu sẽ từ chối cuộc gọi như vậy. hàm có thể nối thêm một phiên bản
Url = str def retry[url: Url, retry_count: int] -> None: ...34 vào danh sách, điều này sẽ vi phạm kiểu của biến trong trình gọi
Hóa ra một đối số như vậy hoạt động trái ngược, trong khi câu trả lời trực quan [đúng trong trường hợp hàm không thay đổi đối số của nó. ] yêu cầu đối số hành động hiệp biến. Bạn có thể tìm thấy phần giới thiệu dài hơn về các khái niệm này trên Wikipedia và trong PEP 483;
Theo mặc định, các loại chung được coi là bất biến trong tất cả các biến loại, điều đó có nghĩa là các giá trị cho các biến được chú thích với các loại như
Url = str def retry[url: Url, retry_count: int] -> None: ...36 phải khớp chính xác với chú thích loại – không có lớp con hoặc siêu lớp nào của tham số loại [trong ví dụ này là
Url = str def retry[url: Url, retry_count: int] -> None: ...34] được phép
Để tạo thuận lợi cho việc khai báo các loại vùng chứa trong đó việc kiểm tra loại hiệp biến hoặc chống biến được chấp nhận, các biến loại chấp nhận các đối số từ khóa
Url = str def retry[url: Url, retry_count: int] -> None: ...41 hoặc
Url = str def retry[url: Url, retry_count: int] -> None: ...42. Nhiều nhất một trong số này có thể được thông qua. Các loại chung được xác định bằng các biến như vậy được coi là đồng biến hoặc chống biến trong biến tương ứng. Theo quy ước, nên sử dụng các tên kết thúc bằng
Url = str def retry[url: Url, retry_count: int] -> None: ...43 cho các biến loại được xác định bằng
Url = str def retry[url: Url, retry_count: int] -> None: ...41 và các tên kết thúc bằng
Url = str def retry[url: Url, retry_count: int] -> None: ...45 cho biến được xác định bằng
Url = str def retry[url: Url, retry_count: int] -> None: ...42
Một ví dụ điển hình liên quan đến việc xác định lớp vùng chứa bất biến [hoặc chỉ đọc]
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]7
Các lớp tập hợp chỉ đọc trong
def greeting[name: str] -> str: return 'Hello ' + name14 đều được khai báo đồng biến trong biến kiểu của chúng [e. g.
Url = str def retry[url: Url, retry_count: int] -> None: ...08 và
def greeting[name: str] -> str: return 'Hello ' + name17]. Các lớp tập hợp có thể thay đổi [e. g.
Url = str def retry[url: Url, retry_count: int] -> None: ...50 và
Url = str def retry[url: Url, retry_count: int] -> None: ...51] được khai báo là bất biến. Một ví dụ về loại trái ngược là loại
Url = str def retry[url: Url, retry_count: int] -> None: ...52, trái ngược với loại đối số
Url = str def retry[url: Url, retry_count: int] -> None: ...53 [xem bên dưới]
Ghi chú. Hiệp phương sai hoặc chống phương sai không phải là thuộc tính của biến loại, mà là thuộc tính của lớp chung được xác định bằng biến này. Phương sai chỉ áp dụng cho các loại chung; . Cái sau chỉ nên được xác định bằng cách sử dụng các biến loại mà không có đối số từ khóa
Url = str def retry[url: Url, retry_count: int] -> None: ...54 hoặc
Url = str def retry[url: Url, retry_count: int] -> None: ...55. Ví dụ như sau cũng được
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]8
trong khi những điều sau đây bị cấm
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]9
PEP 3141 xác định tháp số của Python và mô-đun stdlib
Url = str def retry[url: Url, retry_count: int] -> None: ...56 triển khai các ABC tương ứng [
Url = str def retry[url: Url, retry_count: int] -> None: ...57,
Url = str def retry[url: Url, retry_count: int] -> None: ...58,
Url = str def retry[url: Url, retry_count: int] -> None: ...59,
Url = str def retry[url: Url, retry_count: int] -> None: ...60 và
Url = str def retry[url: Url, retry_count: int] -> None: ...61]. Có một số vấn đề với các ABC này, nhưng các lớp số cụ thể tích hợp sẵn
Url = str def retry[url: Url, retry_count: int] -> None: ...62,
Url = str def retry[url: Url, retry_count: int] -> None: ...63 và
Url = str def retry[url: Url, retry_count: int] -> None: ...64 rất phổ biến [đặc biệt là hai lớp sau. -]
Thay vì yêu cầu người dùng viết
Url = str def retry[url: Url, retry_count: int] -> None: ...65 và sau đó sử dụng
Url = str def retry[url: Url, retry_count: int] -> None: ...66, v.v. , PEP này đề xuất một lối tắt đơn giản gần như hiệu quả. khi một đối số được chú thích là có loại
Url = str def retry[url: Url, retry_count: int] -> None: ...63, thì một đối số loại
Url = str def retry[url: Url, retry_count: int] -> None: ...64 được chấp nhận; . Điều này không xử lý các lớp triển khai ABC tương ứng hoặc lớp
Url = str def retry[url: Url, retry_count: int] -> None: ...72, nhưng chúng tôi tin rằng những trường hợp sử dụng đó cực kỳ hiếm
Khi một gợi ý loại chứa các tên chưa được xác định, định nghĩa đó có thể được biểu thị dưới dạng một chuỗi ký tự, sẽ được giải quyết sau
Một tình huống mà điều này thường xảy ra là định nghĩa của một lớp chứa, trong đó lớp được định nghĩa xuất hiện trong chữ ký của một số phương thức. Ví dụ: đoạn mã sau [bắt đầu triển khai cây nhị phân đơn giản] không hoạt động
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]0
Để giải quyết vấn đề này, chúng tôi viết
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]1
Chuỗi ký tự phải chứa một biểu thức Python hợp lệ [i. e. ,
Url = str def retry[url: Url, retry_count: int] -> None: ...73 phải là một đối tượng mã hợp lệ] và nó sẽ đánh giá mà không có lỗi sau khi mô-đun đã được tải đầy đủ. Không gian tên cục bộ và toàn cầu mà nó được đánh giá phải là cùng một không gian tên trong đó các đối số mặc định cho cùng một chức năng sẽ được đánh giá
Hơn nữa, biểu thức phải được phân tích cú pháp dưới dạng gợi ý loại hợp lệ, tôi. e. , nó bị hạn chế bởi các quy tắc từ phần trên
Ví dụ, được phép sử dụng các chuỗi ký tự như một phần của gợi ý loại
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]2
Một cách sử dụng phổ biến cho các tham chiếu chuyển tiếp là khi e. g. Các mô hình Django là cần thiết trong chữ ký. Thông thường, mỗi mô hình nằm trong một tệp riêng biệt và có các phương thức lấy đối số có loại liên quan đến các mô hình khác. Do cách nhập vòng tròn hoạt động trong Python, thường không thể nhập trực tiếp tất cả các mô hình cần thiết
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]3
Giả sử main được nhập trước, điều này sẽ không thành công với ImportError ở dòng
Url = str def retry[url: Url, retry_count: int] -> None: ...74 trong models/b. py, đang được nhập từ models/a. py trước a đã xác định lớp A. Giải pháp là chuyển sang nhập chỉ theo mô-đun và tham chiếu các mô hình theo _module_ của chúng. _tên lớp
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]4
Vì việc chấp nhận một tập hợp nhỏ, hạn chế các loại dự kiến cho một đối số là phổ biến, nên có một nhà máy đặc biệt mới có tên là
def greeting[name: str] -> str: return 'Hello ' + name42. Thí dụ
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]5
Một loại được tính bởi
Url = str def retry[url: Url, retry_count: int] -> None: ...76 là siêu kiểu của tất cả các loại
Url = str def retry[url: Url, retry_count: int] -> None: ...77,
Url = str def retry[url: Url, retry_count: int] -> None: ...78, v.v. , so that a value that is a member of one of these types is acceptable for an argument annotated by
Url = str def retry[url: Url, retry_count: int] -> None: ...76
Một trường hợp phổ biến của các loại liên kết là các loại tùy chọn. Theo mặc định,
def greeting[name: str] -> str: return 'Hello ' + name40 là một giá trị không hợp lệ cho bất kỳ loại nào, trừ khi giá trị mặc định của
def greeting[name: str] -> str: return 'Hello ' + name40 đã được cung cấp trong định nghĩa hàm. ví dụ
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]6
Để viết tắt cho
Url = str def retry[url: Url, retry_count: int] -> None: ...82, bạn có thể viết
Url = str def retry[url: Url, retry_count: int] -> None: ...83;
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]7
Phiên bản trước đây của PEP này cho phép người kiểm tra loại giả sử một loại tùy chọn khi giá trị mặc định là
def greeting[name: str] -> str: return 'Hello ' + name40, như trong mã này
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]8
Điều này sẽ được coi là tương đương với
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]9
Đây không còn là hành vi được đề xuất. Type checkers should move towards requiring the optional type to be made explicit
Một thể hiện đơn lẻ thường được sử dụng để đánh dấu một số điều kiện đặc biệt, cụ thể là trong các tình huống mà
def greeting[name: str] -> str: return 'Hello ' + name40 cũng là một giá trị hợp lệ cho một biến. Thí dụ
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body0
Để cho phép nhập chính xác trong các tình huống như vậy, người dùng nên sử dụng loại
def greeting[name: str] -> str: return 'Hello ' + name42 kết hợp với lớp
Url = str def retry[url: Url, retry_count: int] -> None: ...87 do thư viện tiêu chuẩn cung cấp, để có thể bắt lỗi loại một cách tĩnh
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body1
Since the subclasses of
Url = str def retry[url: Url, retry_count: int] -> None: ...88 cannot be further subclassed, the type of variable
def greeting[name: str] -> str: return 'Hello ' + name75 can be statically inferred in all branches of the above example. Cách tiếp cận tương tự được áp dụng nếu cần nhiều hơn một đối tượng đơn lẻ. người ta có thể sử dụng một phép liệt kê có nhiều hơn một giá trị
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body2
Một loại đặc biệt của loại là
def greeting[name: str] -> str: return 'Hello ' + name12. Mọi loại đều nhất quán với
def greeting[name: str] -> str: return 'Hello ' + name12. It can be considered a type that has all values and all methods. Note that
def greeting[name: str] -> str: return 'Hello ' + name12 and builtin type
Url = str def retry[url: Url, retry_count: int] -> None: ...94 are completely different
When the type of a value is
Url = str def retry[url: Url, retry_count: int] -> None: ...94, the type checker will reject almost all operations on it, and assigning it to a variable [or using it as a return value] of a more specialized type is a type error. On the other hand, when a value has type
def greeting[name: str] -> str: return 'Hello ' + name12, the type checker will allow all operations on it, and a value of type
def greeting[name: str] -> str: return 'Hello ' + name12 can be assigned to a variable [or used as a return value] of a more constrained type
Một tham số chức năng không có chú thích được coi là có chú thích với
def greeting[name: str] -> str: return 'Hello ' + name12. Nếu một loại chung được sử dụng mà không chỉ định tham số loại, thì chúng được giả định là
def greeting[name: str] -> str: return 'Hello ' + name12
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body3
Quy tắc này cũng áp dụng cho
def greeting[name: str] -> str: return 'Hello ' + name43, trong ngữ cảnh chú thích, nó tương đương với
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]01 và ngược lại, với
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]02. Đồng thời, một
def greeting[name: str] -> str: return 'Hello ' + name44 trần trong một chú thích tương đương với
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]04 và ngược lại, với
def greeting[name: str] -> str: return 'Hello ' + name56
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body4
Mô-đun
def greeting[name: str] -> str: return 'Hello ' + name14 cung cấp một loại đặc biệt
def greeting[name: str] -> str: return 'Hello ' + name13 để chú thích các chức năng không bao giờ trở lại bình thường. Ví dụ, một chức năng đưa ra một ngoại lệ vô điều kiện
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body5
Chú thích
def greeting[name: str] -> str: return 'Hello ' + name13 được sử dụng cho các chức năng như
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]10. Trình kiểm tra kiểu tĩnh sẽ đảm bảo rằng các hàm được chú thích là trả về
def greeting[name: str] -> str: return 'Hello ' + name13 thực sự không bao giờ trả về, dù ngầm hay rõ ràng
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body6
Người kiểm tra cũng sẽ nhận ra rằng mã sau khi gọi các chức năng đó là không thể truy cập được và sẽ hoạt động tương ứng
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body7
Loại
def greeting[name: str] -> str: return 'Hello ' + name13 chỉ hợp lệ dưới dạng chú thích trả về của các hàm và được coi là lỗi nếu nó xuất hiện ở các vị trí khác
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body8
Đôi khi bạn muốn nói về các đối tượng lớp, cụ thể là các đối tượng lớp kế thừa từ một lớp nhất định. Điều này có thể được đánh vần là
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]13 trong đó
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]14 là một lớp học. Làm rõ. trong khi
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]14 [khi được sử dụng làm chú thích] đề cập đến các thể hiện của lớp
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]14, thì
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]13 đề cập đến các lớp con của
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]14. [Đây là sự khác biệt tương tự như giữa
Url = str def retry[url: Url, retry_count: int] -> None: ...94 và
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]20. ]
Ví dụ: giả sử chúng ta có các lớp sau
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body9
Và giả sử chúng ta có một hàm tạo một thể hiện của một trong các lớp này nếu bạn truyền cho nó một đối tượng lớp
def partial[func: Callable[..., str], *args] -> Callable[..., str]: # Body0
Nếu không có
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]21, điều tốt nhất chúng tôi có thể làm để chú thích
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]22 sẽ là
def partial[func: Callable[..., str], *args] -> Callable[..., str]: # Body1
Tuy nhiên, sử dụng
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]21 và biến loại có giới hạn trên, chúng ta có thể làm tốt hơn nhiều
def partial[func: Callable[..., str], *args] -> Callable[..., str]: # Body2
Bây giờ, khi chúng ta gọi
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]22 với một phân lớp cụ thể là
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]25, trình kiểm tra loại sẽ suy ra loại kết quả chính xác
def partial[func: Callable[..., str], *args] -> Callable[..., str]: # Body3
Giá trị tương ứng với
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]13 phải là một đối tượng lớp thực sự là một kiểu con của
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]14, không phải là một dạng đặc biệt. Nói cách khác, trong ví dụ trên gọi e. g.
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]28 bị trình kiểm tra loại từ chối [ngoài việc không thành công trong thời gian chạy vì bạn không thể khởi tạo liên kết]
Lưu ý rằng việc sử dụng tập hợp các lớp làm tham số cho
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]21 là hợp pháp, như trong
def partial[func: Callable[..., str], *args] -> Callable[..., str]: # Body4
Tuy nhiên, đối số thực tế được truyền trong thời gian chạy vẫn phải là một đối tượng lớp cụ thể, e. g. trong ví dụ trên
def partial[func: Callable[..., str], *args] -> Callable[..., str]: # Body5
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]30 cũng được hỗ trợ [xem bên dưới để biết ý nghĩa của nó]
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]31 trong đó
def greeting[name: str] -> str: return 'Hello ' + name82 là biến kiểu được cho phép khi chú thích đối số đầu tiên của phương thức lớp [xem phần liên quan]
Bất kỳ cấu trúc đặc biệt nào khác như
def greeting[name: str] -> str: return 'Hello ' + name43 hoặc
def greeting[name: str] -> str: return 'Hello ' + name44 đều không được phép làm đối số cho
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]35
Có một số lo ngại với tính năng này. ví dụ: khi
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]22 gọi
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]37, điều này ngụ ý rằng tất cả các lớp con của
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]25 phải hỗ trợ điều này trong chữ ký hàm tạo của chúng. Tuy nhiên, đây không phải là duy nhất đối với
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]21. các phương thức lớp có mối quan tâm tương tự. Trình kiểm tra loại phải gắn cờ vi phạm các giả định đó, nhưng theo mặc định, hàm tạo khớp với chữ ký của hàm tạo trong lớp cơ sở được chỉ định [
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]25 trong ví dụ trên] nên được phép. Một chương trình chứa hệ thống phân cấp lớp phức tạp hoặc có thể mở rộng cũng có thể xử lý việc này bằng cách sử dụng phương thức lớp xuất xưởng. Bản sửa đổi trong tương lai của PEP này có thể đưa ra những cách tốt hơn để giải quyết những mối lo ngại này
Khi
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]35 được tham số hóa, nó yêu cầu chính xác một tham số. Đồng bằng
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]35 không có dấu ngoặc đơn tương đương với
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]30 và điều này đến lượt nó tương đương với
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]20 [gốc của hệ thống phân cấp siêu dữ liệu của Python]. Sự tương đương này cũng thúc đẩy tên,
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]35, trái ngược với các lựa chọn thay thế như
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]46 hoặc
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]47, được đề xuất trong khi tính năng này đang được thảo luận; . g.
Url = str def retry[url: Url, retry_count: int] -> None: ...10 và
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]49
Đối với hành vi của
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]30 [hoặc
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]35 hoặc
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]20], việc truy cập các thuộc tính của một biến với loại này chỉ cung cấp các thuộc tính và phương thức được xác định bởi
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]20 [ví dụ:
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]54 và
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]55]. Một biến như vậy có thể được gọi với các đối số tùy ý và kiểu trả về là
def greeting[name: str] -> str: return 'Hello ' + name12
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]35 là biến thể trong tham số của nó, bởi vì
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]58 là một kiểu con của
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]59
def partial[func: Callable[..., str], *args] -> Callable[..., str]: # Body6
Trong hầu hết các trường hợp, đối số đầu tiên của các phương thức lớp và thể hiện không cần phải được chú thích và nó được giả định là có kiểu của lớp chứa đối với các phương thức thể hiện và một kiểu đối tượng kiểu tương ứng với đối tượng lớp chứa đối với các phương thức lớp. Ngoài ra, đối số đầu tiên trong một phương thức thể hiện có thể được chú thích bằng một biến kiểu. Trong trường hợp này, kiểu trả về có thể sử dụng cùng một biến kiểu, do đó làm cho phương thức đó trở thành một hàm chung. Ví dụ
def partial[func: Callable[..., str], *args] -> Callable[..., str]: # Body7
Điều tương tự cũng áp dụng cho các phương thức lớp sử dụng
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]21 trong chú thích của đối số đầu tiên
def partial[func: Callable[..., str], *args] -> Callable[..., str]: # Body8
Lưu ý rằng một số trình kiểm tra loại có thể áp dụng các hạn chế đối với việc sử dụng này, chẳng hạn như yêu cầu giới hạn trên thích hợp cho biến loại được sử dụng [xem ví dụ]
Trình kiểm tra loại dự kiến sẽ hiểu các kiểm tra nền tảng và phiên bản đơn giản, e. g
def partial[func: Callable[..., str], *args] -> Callable[..., str]: # Body9
Đừng mong đợi một người kiểm tra hiểu được những điều khó hiểu như
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]61
Đôi khi, có mã phải được trình kiểm tra loại [hoặc các công cụ phân tích tĩnh khác] nhìn thấy nhưng không được thực thi. Đối với những tình huống như vậy, mô-đun
def greeting[name: str] -> str: return 'Hello ' + name14 xác định một hằng số,
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]63, được coi là
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]64 trong quá trình kiểm tra loại [hoặc phân tích tĩnh khác] nhưng lại là
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]65 trong thời gian chạy. Thí dụ
from typing import Mapping, Set def notify_by_email[employees: Set[Employee], overrides: Mapping[str, str]] -> None: ...0
[Lưu ý rằng chú thích loại phải được đặt trong dấu ngoặc kép, làm cho nó trở thành "tham chiếu chuyển tiếp", để ẩn tham chiếu
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]66 khỏi thời gian chạy trình thông dịch. Trong bình luận
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]67 không cần trích dẫn. ]
Cách tiếp cận này cũng có thể hữu ích để xử lý các chu kỳ nhập
Danh sách đối số tùy ý cũng có thể được chú thích kiểu, để định nghĩa
from typing import Mapping, Set def notify_by_email[employees: Set[Employee], overrides: Mapping[str, str]] -> None: ...1
là chấp nhận được và nó có nghĩa là, e. g. , tất cả các lệnh gọi hàm sau đây có các loại đối số hợp lệ
from typing import Mapping, Set def notify_by_email[employees: Set[Employee], overrides: Mapping[str, str]] -> None: ...2
Trong thân hàm
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]68, kiểu của biến
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]69 được suy ra là
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]70 và kiểu của biến
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]71 là
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]72
Trong sơ khai, có thể hữu ích khi khai báo một đối số là có giá trị mặc định mà không chỉ định giá trị mặc định thực tế. Ví dụ
from typing import Mapping, Set def notify_by_email[employees: Set[Employee], overrides: Mapping[str, str]] -> None: ...3
Giá trị mặc định sẽ như thế nào?
Trong những trường hợp như vậy, giá trị mặc định có thể được chỉ định dưới dạng dấu chấm lửng, tôi. e. ví dụ trên đúng nghĩa là những gì bạn sẽ viết
Một số hàm được thiết kế để chỉ lấy các đối số của chúng theo vị trí và yêu cầu người gọi chúng không bao giờ sử dụng tên của đối số để cung cấp đối số đó theo từ khóa. Tất cả các đối số có tên bắt đầu bằng
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]76 được coi là chỉ có vị trí, trừ khi tên của chúng cũng kết thúc bằng
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]76
from typing import Mapping, Set def notify_by_email[employees: Set[Employee], overrides: Mapping[str, str]] -> None: ...4
Kiểu trả về của các hàm tạo có thể được chú thích bằng kiểu chung
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]78 được cung cấp bởi mô-đun
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]79
from typing import Mapping, Set def notify_by_email[employees: Set[Employee], overrides: Mapping[str, str]] -> None: ...5
Các coroutine được giới thiệu trong PEP 492 được chú thích với cú pháp giống như các hàm thông thường. Tuy nhiên, chú thích kiểu trả về tương ứng với kiểu của biểu thức
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]80, không phải kiểu coroutine
from typing import Mapping, Set def notify_by_email[employees: Set[Employee], overrides: Mapping[str, str]] -> None: ...6
Mô-đun
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]79 cung cấp một phiên bản chung của ABC
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]82 để chỉ định các nội dung có thể chờ đợi cũng hỗ trợ các phương thức
Url = str def retry[url: Url, retry_count: int] -> None: ...53 và
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]84. Phương sai và thứ tự của các biến loại tương ứng với biến của
Url = str def retry[url: Url, retry_count: int] -> None: ...52, cụ thể là
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]86 chẳng hạn
from typing import Mapping, Set def notify_by_email[employees: Set[Employee], overrides: Mapping[str, str]] -> None: ...7
Mô-đun này cũng cung cấp các ABC chung
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]87,
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]88 và
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]89 cho các tình huống không thể chỉ định các loại chính xác hơn
from typing import Mapping, Set def notify_by_email[employees: Set[Employee], overrides: Mapping[str, str]] -> None: ...8
Một số trường hợp sử dụng hiện có hoặc tiềm năng cho chú thích chức năng tồn tại, không tương thích với gợi ý loại. Những điều này có thể gây nhầm lẫn cho trình kiểm tra kiểu tĩnh. Tuy nhiên, vì các chú thích gợi ý kiểu không có hành vi trong thời gian chạy [ngoài việc đánh giá biểu thức chú thích và lưu trữ các chú thích trong thuộc tính
def greeting[name: str] -> str: return 'Hello ' + name15 của đối tượng hàm], điều này không làm cho chương trình không chính xác – nó chỉ có thể khiến trình kiểm tra kiểu đưa ra các cảnh báo giả mạo
Để đánh dấu các phần của chương trình không được bao phủ bởi gợi ý loại, bạn có thể sử dụng một hoặc nhiều cách sau
- một bình luận
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]
91; - một trang trí
def greeting[name: str] -> str: return 'Hello ' + name
23 trên một lớp hoặc chức năng; - một lớp tùy chỉnh hoặc trình trang trí chức năng được đánh dấu bằng
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]
93
Để biết thêm chi tiết xem các phần sau
Để có khả năng tương thích tối đa với kiểm tra loại ngoại tuyến, cuối cùng, có thể nên thay đổi các giao diện dựa trên chú thích để chuyển sang một cơ chế khác, chẳng hạn như trình trang trí. Trong Trăn 3. 5 không có áp lực để làm điều này, tuy nhiên. Xem thêm cuộc thảo luận dài hơn bên dưới
PEP này không hỗ trợ cú pháp hạng nhất để đánh dấu rõ ràng các biến là thuộc một loại cụ thể. Để giúp suy luận kiểu trong các trường hợp phức tạp, có thể sử dụng nhận xét có định dạng sau
from typing import Mapping, Set def notify_by_email[employees: Set[Employee], overrides: Mapping[str, str]] -> None: ...9
Loại nhận xét nên được đặt trên dòng cuối cùng của câu lệnh có chứa định nghĩa biến. Chúng cũng có thể được đặt trên câu lệnh
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]94 và câu lệnh
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]95, ngay sau dấu hai chấm
Ví dụ về nhận xét loại trên câu lệnh
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]94 và
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]95
from typing import Sequence, TypeVar T = TypeVar['T'] # Declare type variable def first[l: Sequence[T]] -> T: # Generic function return l[0]0
Trong sơ khai, có thể hữu ích khi khai báo sự tồn tại của một biến mà không cho nó một giá trị ban đầu. Điều này có thể được thực hiện bằng cách sử dụng cú pháp chú thích biến PEP 526
from typing import Sequence, TypeVar T = TypeVar['T'] # Declare type variable def first[l: Sequence[T]] -> T: # Generic function return l[0]1
Cú pháp trên được chấp nhận trong sơ khai cho tất cả các phiên bản Python. Tuy nhiên, trong mã không còn sơ khai cho các phiên bản Python 3. 5 trở về trước có trường hợp đặc biệt
from typing import Sequence, TypeVar T = TypeVar['T'] # Declare type variable def first[l: Sequence[T]] -> T: # Generic function return l[0]2
Người kiểm tra loại không nên phàn nàn về điều này [mặc dù giá trị
def greeting[name: str] -> str: return 'Hello ' + name40 không khớp với loại đã cho], họ cũng không nên thay đổi loại được suy luận thành
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]99 [bất chấp quy tắc thực hiện điều này đối với các đối số được chú thích có giá trị mặc định là
def greeting[name: str] -> str: return 'Hello ' + name40]. Giả định ở đây là mã khác sẽ đảm bảo rằng biến được cung cấp một giá trị của loại phù hợp và tất cả các cách sử dụng có thể giả định rằng biến có loại đã cho
Nhận xét
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]91 phải được đặt trên dòng liên quan đến lỗi
from typing import Sequence, TypeVar T = TypeVar['T'] # Declare type variable def first[l: Sequence[T]] -> T: # Generic function return l[0]3
Một nhận xét
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]91 trên một dòng ở đầu tệp, trước bất kỳ chuỗi tài liệu, nhập hoặc mã thực thi nào khác, tắt tất cả các lỗi trong tệp. Các dòng trống và các nhận xét khác, chẳng hạn như các dòng shebang và cookie mã hóa, có thể đứng trước nhận xét
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]91
Trong một số trường hợp, có thể cần các công cụ linting hoặc các chú thích khác trên cùng một dòng với chú thích loại. Trong những trường hợp này, loại nhận xét phải ở trước các nhận xét khác và đánh dấu linting
# type: ignore #
Nếu gợi ý kiểu nói chung hữu ích, một cú pháp để gõ biến có thể được cung cấp trong phiên bản Python trong tương lai. [CẬP NHẬT. Cú pháp này đã được thêm vào Python 3. 6 đến PEP 526. ]
Đôi khi trình kiểm tra loại có thể cần một loại gợi ý khác. lập trình viên có thể biết rằng một biểu thức thuộc loại bị ràng buộc hơn so với trình kiểm tra loại có thể suy ra. Ví dụ
from typing import Sequence, TypeVar T = TypeVar['T'] # Declare type variable def first[l: Sequence[T]] -> T: # Generic function return l[0]4
Một số trình kiểm tra loại có thể không thể suy luận rằng loại
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]04 là
def greeting[name: str] -> str: return 'Hello ' + name37 và chỉ suy ra
Url = str def retry[url: Url, retry_count: int] -> None: ...94 hoặc
def greeting[name: str] -> str: return 'Hello ' + name12, nhưng chúng tôi biết rằng [nếu mã đạt đến điểm đó] thì đó phải là một chuỗi. Cuộc gọi
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]08 cho người kiểm tra loại biết rằng chúng tôi tự tin rằng loại
def greeting[name: str] -> str: return 'Hello ' + name75 là
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]10. Trong thời gian chạy, một phép truyền luôn trả về biểu thức không thay đổi – nó không kiểm tra loại và nó không chuyển đổi hoặc ép buộc giá trị
Diễn viên khác với nhận xét loại [xem phần trước]. Khi sử dụng nhận xét loại, trình kiểm tra loại vẫn phải xác minh rằng loại được suy luận phù hợp với loại đã nêu. Khi sử dụng ép kiểu, người kiểm tra kiểu nên tin tưởng người lập trình một cách mù quáng. Ngoài ra, các phép ép kiểu có thể được sử dụng trong các biểu thức, trong khi các nhận xét kiểu chỉ áp dụng cho các bài tập
Cũng có những tình huống mà một lập trình viên có thể muốn tránh các lỗi logic bằng cách tạo các lớp đơn giản. Ví dụ
from typing import Sequence, TypeVar T = TypeVar['T'] # Declare type variable def first[l: Sequence[T]] -> T: # Generic function return l[0]5
Tuy nhiên, cách tiếp cận này giới thiệu một chi phí thời gian chạy. Để tránh điều này,
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]79 cung cấp hàm trợ giúp
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]12 để tạo các kiểu duy nhất đơn giản với chi phí thời gian chạy gần như bằng không. Đối với trình kiểm tra kiểu tĩnh,
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]13 gần tương đương với định nghĩa
from typing import Sequence, TypeVar T = TypeVar['T'] # Declare type variable def first[l: Sequence[T]] -> T: # Generic function return l[0]6
Trong thời gian chạy,
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]14 trả về một hàm giả chỉ trả về đối số của nó. Trình kiểm tra loại yêu cầu chuyển kiểu rõ ràng từ
Url = str def retry[url: Url, retry_count: int] -> None: ...64 trong đó dự kiến là
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]16, trong khi chuyển kiểu ngầm định từ
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]16 trong đó dự kiến là
Url = str def retry[url: Url, retry_count: int] -> None: ...64. ví dụ
from typing import Sequence, TypeVar T = TypeVar['T'] # Declare type variable def first[l: Sequence[T]] -> T: # Generic function return l[0]7
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]12 chấp nhận chính xác hai đối số. một tên cho loại duy nhất mới và một lớp cơ sở. Cái sau phải là một lớp thích hợp [tôi. e. , không phải là cấu trúc kiểu như
def greeting[name: str] -> str: return 'Hello ' + name42, v.v. ] hoặc một loại duy nhất khác được tạo bằng cách gọi
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]12. Hàm được trả về bởi
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]12 chỉ chấp nhận một đối số; . Thí dụ
from typing import Sequence, TypeVar T = TypeVar['T'] # Declare type variable def first[l: Sequence[T]] -> T: # Generic function return l[0]8
Cả
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]23 và
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]24, cũng như việc phân lớp con sẽ không thành công đối với
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]14 vì các đối tượng hàm không hỗ trợ các thao tác này
Các tệp sơ khai là các tệp chứa gợi ý loại chỉ được sử dụng bởi trình kiểm tra loại, không phải trong thời gian chạy. There are several use cases for stub files
- mô-đun mở rộng
- Các mô-đun của bên thứ ba mà tác giả chưa thêm gợi ý loại
- Các mô-đun thư viện tiêu chuẩn chưa viết gợi ý loại
- Các mô-đun phải tương thích với Python 2 và 3
- Các mô-đun sử dụng chú thích cho các mục đích khác
Các tệp sơ khai có cú pháp giống như các mô-đun Python thông thường. Có một tính năng của mô-đun
def greeting[name: str] -> str: return 'Hello ' + name14 khác trong tệp sơ khai. người trang trí
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]27 được mô tả bên dưới
Trình kiểm tra kiểu chỉ nên kiểm tra chữ ký hàm trong tệp sơ khai;
Trình kiểm tra loại phải có đường dẫn tìm kiếm có thể định cấu hình cho các tệp sơ khai. Nếu một tệp sơ khai được tìm thấy, trình kiểm tra loại sẽ không đọc mô-đun “thực” tương ứng
Mặc dù các tệp sơ khai là các mô-đun Python hợp lệ về mặt cú pháp, nhưng chúng sử dụng phần mở rộng
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]29 để có thể duy trì các tệp sơ khai trong cùng thư mục với mô-đun thực tương ứng. Điều này cũng củng cố quan điểm rằng không nên có hành vi thời gian chạy đối với các tệp sơ khai
Ghi chú bổ sung về các tập tin sơ khai
- Các mô-đun và biến được nhập vào sơ khai không được coi là đã xuất từ sơ khai trừ khi quá trình nhập sử dụng biểu mẫu
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
30 hoặc biểu mẫu tương đươngfrom typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
31. [CẬP NHẬT. Để làm rõ, mục đích ở đây là chỉ những tên được nhập bằng biểu mẫufrom typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
32 mới được xuất, tôi. e. tên trước và saufrom typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
33 phải giống nhau. ] - Tuy nhiên, như một ngoại lệ đối với dấu đầu dòng trước đó, tất cả các đối tượng được nhập vào sơ khai bằng cách sử dụng
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
34 được coi là đã xuất. [Điều này giúp dễ dàng xuất lại tất cả các đối tượng từ một mô-đun nhất định có thể thay đổi theo phiên bản Python. ] - Giống như trong , các mô-đun con tự động trở thành thuộc tính xuất của mô-đun mẹ khi được nhập. Ví dụ: nếu gói
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
35 có cấu trúc thư mục saufrom typing import Sequence, TypeVar T = TypeVar['T'] # Declare type variable def first[l: Sequence[T]] -> T: # Generic function return l[0]
9trong đó
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
36 chứa một dòng chẳng hạn nhưfrom typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
37 hoặcfrom typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
38, thìfrom typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
39 là thuộc tính được xuất củafrom typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
35 - Tệp sơ khai có thể không đầy đủ. Để làm cho trình kiểm tra loại biết điều này, tệp có thể chứa đoạn mã sau
from typing import TypeVar, Text AnyStr = TypeVar['AnyStr', Text, bytes] def concat[x: AnyStr, y: AnyStr] -> AnyStr: return x + y
0Do đó, bất kỳ mã định danh nào không được xác định trong sơ khai đều được coi là thuộc loại
def greeting[name: str] -> str: return 'Hello ' + name
12
Trình trang trí
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]27 cho phép mô tả các hàm và phương thức hỗ trợ nhiều kiểu kết hợp đối số khác nhau. Mẫu này được sử dụng thường xuyên trong các loại và mô-đun dựng sẵn. Ví dụ, phương pháp
def greeting[name: str] -> str: return 'Hello ' + name20 của loại
def greeting[name: str] -> str: return 'Hello ' + name66 có thể được mô tả như sau
from typing import TypeVar, Text AnyStr = TypeVar['AnyStr', Text, bytes] def concat[x: AnyStr, y: AnyStr] -> AnyStr: return x + y1
Mô tả này chính xác hơn so với khả năng sử dụng các liên kết [không thể diễn tả mối quan hệ giữa đối số và kiểu trả về]
from typing import TypeVar, Text AnyStr = TypeVar['AnyStr', Text, bytes] def concat[x: AnyStr, y: AnyStr] -> AnyStr: return x + y2
Một ví dụ khác trong đó
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]27 có ích là loại hàm dựng sẵn
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]46, hàm này nhận số lượng đối số khác nhau tùy thuộc vào loại của hàm có thể gọi được
from typing import TypeVar, Text AnyStr = TypeVar['AnyStr', Text, bytes] def concat[x: AnyStr, y: AnyStr] -> AnyStr: return x + y3
Lưu ý rằng chúng tôi cũng có thể dễ dàng thêm các mục để hỗ trợ
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]47
from typing import TypeVar, Text AnyStr = TypeVar['AnyStr', Text, bytes] def concat[x: AnyStr, y: AnyStr] -> AnyStr: return x + y4
Việc sử dụng trình trang trí
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]27 như được hiển thị ở trên phù hợp với các tệp sơ khai. Trong các mô-đun thông thường, một loạt các định nghĩa được trang trí bằng
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]27 phải được theo sau bởi chính xác một định nghĩa không được trang trí ____42_______27 [cho cùng một chức năng/phương pháp]. Các định nghĩa được trang trí _
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]27 chỉ dành cho lợi ích của trình kiểm tra loại, vì chúng sẽ bị ghi đè bởi định nghĩa không được trang trí ____42_______27, trong khi định nghĩa sau được sử dụng trong thời gian chạy nhưng trình kiểm tra loại sẽ bỏ qua. Trong thời gian chạy, việc gọi trực tiếp một hàm được trang trí
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]27 sẽ tăng
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]54. Đây là một ví dụ về tình trạng quá tải không sơ khai không thể dễ dàng biểu thị bằng cách sử dụng biến kết hợp hoặc biến loại
from typing import TypeVar, Text AnyStr = TypeVar['AnyStr', Text, bytes] def concat[x: AnyStr, y: AnyStr] -> AnyStr: return x + y5
GHI CHÚ. Mặc dù có thể cung cấp triển khai nhiều công văn bằng cách sử dụng cú pháp này, nhưng việc triển khai nó sẽ yêu cầu sử dụng
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]55, điều này không được tán thành. Ngoài ra, việc thiết kế và triển khai một cơ chế điều phối nhiều lần hiệu quả là rất khó, đó là lý do tại sao những nỗ lực trước đó đã bị bỏ rơi để thay thế cho
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]56. [Xem PEP 443, đặc biệt là phần “Các phương pháp thay thế”. ] Trong tương lai, chúng tôi có thể đưa ra một thiết kế nhiều công văn thỏa đáng, nhưng chúng tôi không muốn một thiết kế như vậy bị hạn chế bởi quá tải cú pháp được xác định cho các gợi ý loại trong tệp sơ khai. Cũng có thể cả hai tính năng sẽ phát triển độc lập với nhau [vì quá tải trong trình kiểm tra loại có các trường hợp và yêu cầu sử dụng khác với nhiều lần gửi trong thời gian chạy – e. g. cái sau không có khả năng hỗ trợ các loại chung]
Thường có thể sử dụng loại
def greeting[name: str] -> str: return 'Hello ' + name61 bị ràng buộc thay vì sử dụng trình trang trí
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]27. Ví dụ: các định nghĩa của
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]59 và
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]60 trong tệp sơ khai này là tương đương
from typing import TypeVar, Text AnyStr = TypeVar['AnyStr', Text, bytes] def concat[x: AnyStr, y: AnyStr] -> AnyStr: return x + y6
Một số chức năng, chẳng hạn như
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]61 hoặc
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]62 ở trên, không thể được biểu diễn chính xác bằng các biến loại. Tuy nhiên, không giống như
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]27, các biến kiểu cũng có thể được sử dụng bên ngoài các tệp sơ khai. Chúng tôi khuyên rằng chỉ nên sử dụng
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]27 trong trường hợp biến loại không đủ, do trạng thái chỉ sơ khai đặc biệt của nó
Một sự khác biệt quan trọng khác giữa các biến loại như
def greeting[name: str] -> str: return 'Hello ' + name72 và sử dụng
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]27 là biến trước đó cũng có thể được sử dụng để xác định các ràng buộc cho các tham số loại chung của lớp. Ví dụ: tham số kiểu của lớp chung
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]67 bị ràng buộc [chỉ
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]68,
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]69 và
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]70 là hợp lệ]
from typing import TypeVar, Text AnyStr = TypeVar['AnyStr', Text, bytes] def concat[x: AnyStr, y: AnyStr] -> AnyStr: return x + y7
Hình thức lưu trữ và phân phối tệp sơ khai dễ dàng nhất là đặt chúng cùng với các mô-đun Python trong cùng một thư mục. Điều này làm cho chúng dễ dàng tìm thấy bởi cả người lập trình và công cụ. Tuy nhiên, vì các nhà bảo trì gói được tự do không thêm gợi ý loại vào các gói của họ, các sơ khai của bên thứ ba có thể cài đặt bởi
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]71 từ PyPI cũng được hỗ trợ. Trong trường hợp này chúng ta phải xem xét ba vấn đề. đặt tên, phiên bản, đường dẫn cài đặt
PEP này không cung cấp đề xuất về sơ đồ đặt tên nên được sử dụng cho các gói tệp sơ khai của bên thứ ba. Khả năng khám phá hy vọng sẽ dựa trên mức độ phổ biến của gói, chẳng hạn như với các gói Django
Sơ khai của bên thứ ba phải được phiên bản bằng phiên bản thấp nhất của gói nguồn tương thích. Thí dụ. FooPackage có phiên bản 1. 0, 1. 1, 1. 2, 1. 3, 2. 0, 2. 1, 2. 2. Có những thay đổi API trong phiên bản 1. 1, 2. 0 và 2. 2. Bộ duy trì gói tệp sơ khai được miễn phí phát hành sơ khai cho tất cả các phiên bản nhưng ít nhất 1. 0, 1. 1, 2. 0 và 2. Cần có 2 để kích hoạt loại người dùng cuối kiểm tra tất cả các phiên bản. Điều này là do người dùng biết rằng phiên bản sơ khai thấp hơn hoặc bằng gần nhất là tương thích. Trong ví dụ được cung cấp, đối với FooPackage 1. 3 người dùng sẽ chọn sơ khai phiên bản 1. 1
Lưu ý rằng nếu người dùng quyết định sử dụng gói nguồn có sẵn "mới nhất", thì việc sử dụng các tệp sơ khai "mới nhất" cũng sẽ hoạt động nếu chúng được cập nhật thường xuyên
Gói sơ khai của bên thứ ba có thể sử dụng bất kỳ vị trí nào để lưu trữ sơ khai. Trình kiểm tra loại nên tìm kiếm chúng bằng PYTHONPATH. Thư mục dự phòng mặc định luôn được chọn là
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]72 [đối với một số PythonX. Y như được xác định bởi trình kiểm tra loại, không chỉ phiên bản đã cài đặt]. Vì chỉ có thể có một gói được cài đặt cho một phiên bản Python nhất định cho mỗi môi trường, nên không có phiên bản bổ sung nào được thực hiện trong thư mục đó [giống như cài đặt thư mục trống bởi
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]71 trong gói trang web]. Tác giả gói tệp sơ khai có thể sử dụng đoạn mã sau trong
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]74
from typing import TypeVar, Text AnyStr = TypeVar['AnyStr', Text, bytes] def concat[x: AnyStr, y: AnyStr] -> AnyStr: return x + y8
[CẬP NHẬT. Kể từ tháng 6 năm 2018, cách được đề xuất để phân phối gợi ý loại cho các gói của bên thứ ba đã thay đổi – ngoài cách đánh máy [xem phần tiếp theo], giờ đây còn có một tiêu chuẩn để phân phối gợi ý loại, PEP 561. It supports separately installable packages containing stubs, stub files included in the same distribution as the executable code of a package, and inline type hints, the latter two options enabled by including a file named
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]75 in the package. ]
There is a shared repository where useful stubs are being collected. Policies regarding the stubs collected here will be decided separately and reported in the repo’s documentation. Note that stubs for a given package will not be included here if the package owners have specifically requested that they be omitted
No syntax for listing explicitly raised exceptions is proposed. Currently the only known use case for this feature is documentational, in which case the recommendation is to put this information in a docstring
To open the usage of static type checking to Python 3. 5 as well as older versions, a uniform namespace is required. For this purpose, a new module in the standard library is introduced called
def greeting[name: str] -> str: return 'Hello ' + name14
It defines the fundamental building blocks for constructing types [e. g.
def greeting[name: str] -> str: return 'Hello ' + name12], types representing generic variants of builtin collections [e. g.
Url = str def retry[url: Url, retry_count: int] -> None: ...10], types representing generic collection ABCs [e. g.
def greeting[name: str] -> str: return 'Hello ' + name17], and a small collection of convenience definitions
Note that special type constructs, such as
def greeting[name: str] -> str: return 'Hello ' + name12,
def greeting[name: str] -> str: return 'Hello ' + name42, and type variables defined using
def greeting[name: str] -> str: return 'Hello ' + name61 are only supported in the type annotation context, and
def greeting[name: str] -> str: return 'Hello ' + name79 may only be used as a base class. All of these [except for unparameterized generics] will raise
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]85 if appear in
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]23 or
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]24
Fundamental building blocks
- Any, used as
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
88 - Union, used as
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
89 - Callable, used as
def greeting[name: str] -> str: return 'Hello ' + name
53 - Tuple, used by listing the element types, for example
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
91. The empty tuple can be typed asfrom typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
92. Arbitrary-length homogeneous tuples can be expressed using one type and ellipsis, for examplefrom typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
93. [Thefrom typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
28 here are part of the syntax, a literal ellipsis. ] - TypeVar, được sử dụng là
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
95 hoặc đơn giản làfrom typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
96 [xem bên trên để biết thêm chi tiết] - Generic, used to create user-defined generic classes
- Type, used to annotate class objects
Generic variants of builtin collections
- Dict, used as
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
97 - DefaultDict, used as
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
98, a generic variant offrom typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
99 - List, used as
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
00 - Set, used as
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
01. Xem nhận xét chofrom typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
02 bên dưới - FrozenSet, used as
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
03
Ghi chú.
def greeting[name: str] -> str: return 'Hello ' + name47,
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body05,
Url = str def retry[url: Url, retry_count: int] -> None: ...10,
Url = str def retry[url: Url, retry_count: int] -> None: ...12 và
Url = str def retry[url: Url, retry_count: int] -> None: ...13 chủ yếu hữu ích cho việc chú thích các giá trị trả về. Đối với các đối số, hãy ưu tiên các loại tập hợp trừu tượng được xác định bên dưới, e. g.
Url = str def retry[url: Url, retry_count: int] -> None: ...08,
def greeting[name: str] -> str: return 'Hello ' + name17 hoặc
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body02
Các biến thể chung của ABC vùng chứa [và một số không phải vùng chứa]
- chờ đợi
- Không đồng bộ
- AsyncIterator
- Chuỗi byte
- Có thể gọi được [xem ở trên, liệt kê ở đây cho đầy đủ]
- Bộ sưu tập
- Thùng đựng hàng
- Trình quản lý bối cảnh
- quy trình
- Máy phát điện, được sử dụng như
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]
78. Điều này thể hiện giá trị trả về của các hàm tạo. Nó là một kiểu con củafrom typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
13 và nó có các biến kiểu bổ sung cho kiểu được chấp nhận bởi phương thứcUrl = str def retry[url: Url, retry_count: int] -> None: ...
53 [có mâu thuẫn trong biến này – một trình tạo chấp nhận gửi nó, ví dụUrl = str def retry[url: Url, retry_count: int] -> None: ...
34 là hợp lệ trong ngữ cảnh yêu cầu một trình tạo chấp nhận gửi nó - Có thể băm [không chung chung, nhưng hiện tại để hoàn thiện]
- MụcXem
- Có thể lặp lại
- Iterator
- PhímXem
- lập bản đồ
- Chế độ xem bản đồ
- Lập bản đồ có thể thay đổi
- MutableSequence
- Bộ thay đổi
- Sự liên tiếp
- Đặt, đổi tên thành
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
02. Việc thay đổi tên này là bắt buộc vìUrl = str def retry[url: Url, retry_count: int] -> None: ...
12 trong mô-đundef greeting[name: str] -> str: return 'Hello ' + name
14 có nghĩa làfrom typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
20 với thuốc generic - Kích thước [không chung chung, nhưng hiện tại cho đầy đủ]
- Giá trịXem
Một số loại dùng một lần được xác định để kiểm tra các phương pháp đặc biệt đơn lẻ [tương tự như
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body21 hoặc
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body22]
- Có thể đảo ngược, để kiểm tra
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
23 - Hỗ trợAbs, để kiểm tra
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
24 - SupportsComplex, để kiểm tra
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
25 - SupportsFloat, để kiểm tra
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
26 - SupportsInt, để kiểm tra
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
27 - SupportsRound, để kiểm tra
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
28 - SupportsBytes, để kiểm tra
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
29
định nghĩa tiện lợi
- Tùy chọn, được xác định bởi
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
30 - Văn bản, bí danh đơn giản cho
def greeting[name: str] -> str: return 'Hello ' + name
37 trong Python 3, chofrom typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
32 trong Python 2 - AnyStr, được định nghĩa là
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
33 - NamedTuple, được sử dụng như
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
34 và tương đương vớifrom typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
35. Điều này hữu ích để khai báo các loại trường của loại bộ được đặt tên - NewType, được sử dụng để tạo các loại duy nhất với ít chi phí thời gian chạy
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
36 - cast[], được mô tả trước đó
- @no_type_check, một trình trang trí để tắt tính năng kiểm tra loại trên mỗi lớp hoặc chức năng [xem bên dưới]
- @no_type_check_decorator, một công cụ trang trí để tạo các công cụ trang trí của riêng bạn với ý nghĩa tương tự như
def greeting[name: str] -> str: return 'Hello ' + name
23 [xem bên dưới] - @type_check_only, một trình trang trí chỉ khả dụng trong quá trình kiểm tra kiểu để sử dụng trong các tệp sơ khai [xem bên trên];
- @overload, được mô tả trước đó
- get_type_hints[], một hàm tiện ích để truy xuất các gợi ý kiểu từ một hàm hoặc phương thức. Đưa ra một đối tượng hàm hoặc phương thức, nó trả về một lệnh có cùng định dạng như
def greeting[name: str] -> str: return 'Hello ' + name
15, nhưng đánh giá các tham chiếu chuyển tiếp [được đưa ra dưới dạng chuỗi ký tự] dưới dạng các biểu thức trong ngữ cảnh của định nghĩa phương thức hoặc hàm ban đầu - TYPE_CHECKING,
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]
65 khi chạy nhưngfrom typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]
64 để nhập trình kiểm tra
Các loại liên quan đến I/O
- IO [chung trên
def greeting[name: str] -> str: return 'Hello ' + name
72] - BinaryIO [một kiểu con đơn giản của
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
69] - TextIO [một kiểu con đơn giản của
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] def inproduct[v: Iterable[Tuple[T, T]]] -> T: return sum[x*y for x, y in v] def dilate[v: Iterable[Tuple[T, T]], scale: T] -> Iterable[Tuple[T, T]]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Iterable[Tuple[float, float]]
68]
Các loại liên quan đến biểu thức chính quy và mô-đun
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body44
- So khớp và Mẫu, các loại kết quả
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
45 vàfrom typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
46 [chung trêndef greeting[name: str] -> str: return 'Hello ' + name
72]
Một số công cụ có thể muốn hỗ trợ chú thích loại trong mã phải tương thích với Python 2. 7. Vì mục đích này, PEP này có phần mở rộng được đề xuất [nhưng không bắt buộc] trong đó các chú thích chức năng được đặt trong một nhận xét
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body48. Một bình luận như vậy phải được đặt ngay sau tiêu đề chức năng [trước chuỗi tài liệu]. Một ví dụ. mã Python 3 sau đây
from typing import TypeVar, Text AnyStr = TypeVar['AnyStr', Text, bytes] def concat[x: AnyStr, y: AnyStr] -> AnyStr: return x + y9
tương đương như sau
def greeting[name: str] -> str: return 'Hello ' + name00
Lưu ý rằng đối với các phương thức, không cần loại cho
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body49
Đối với một phương thức không có đối số, nó sẽ trông như thế này
def greeting[name: str] -> str: return 'Hello ' + name01
Đôi khi bạn muốn chỉ định kiểu trả về cho một hàm hoặc phương thức mà không [chưa] chỉ định các kiểu đối số. Để hỗ trợ điều này một cách rõ ràng, danh sách đối số có thể được thay thế bằng dấu chấm lửng. Thí dụ
def greeting[name: str] -> str: return 'Hello ' + name02
Đôi khi bạn có một danh sách dài các tham số và việc chỉ định loại của chúng trong một nhận xét
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body48 sẽ rất khó xử. Để đạt được điều này, bạn có thể liệt kê một đối số trên mỗi dòng và thêm một nhận xét
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body48 trên mỗi dòng sau dấu phẩy liên quan của đối số, nếu có. Để chỉ định kiểu trả về, hãy sử dụng cú pháp dấu chấm lửng. Việc chỉ định kiểu trả về là không bắt buộc và không phải mọi đối số đều cần được cung cấp một kiểu. Một dòng có nhận xét
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body48 phải chứa chính xác một đối số. Nhận xét loại cho đối số cuối cùng [nếu có] phải đứng trước dấu ngoặc đơn đóng. Thí dụ
def greeting[name: str] -> str: return 'Hello ' + name03
ghi chú
- Các công cụ hỗ trợ cú pháp này sẽ hỗ trợ nó bất kể phiên bản Python đang được kiểm tra. Điều này là cần thiết để hỗ trợ mã nằm giữa Python 2 và Python 3
- Không được phép đối số hoặc giá trị trả về có cả chú thích kiểu và chú thích kiểu
- Khi sử dụng dạng rút gọn [e. g.
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
53] mọi đối số phải được tính đến, ngoại trừ đối số đầu tiên của các phương thức thể hiện và lớp [những đối số này thường được bỏ qua, nhưng được phép đưa vào] - Loại trả về là bắt buộc đối với biểu mẫu ngắn. Nếu trong Python 3, bạn sẽ bỏ qua một số đối số hoặc kiểu trả về, thì ký hiệu Python 2 nên sử dụng
def greeting[name: str] -> str: return 'Hello ' + name
12 - Khi sử dụng dạng rút gọn, đối với
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
55 vàfrom typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
56, hãy đặt 1 hoặc 2 sao trước chú thích loại tương ứng. [Giống như chú thích Python 3, chú thích ở đây biểu thị loại giá trị đối số riêng lẻ, không phải của bộ/dict mà bạn nhận được dưới dạng giá trị đối số đặc biệtfrom typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]
69 hoặcfrom typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]
71. ] - Like other type comments, any names used in the annotations must be imported or defined by the module containing the annotation
- Khi sử dụng dạng viết tắt, toàn bộ chú thích phải là một dòng
- Dạng rút gọn cũng có thể xuất hiện trên cùng một dòng với dấu ngoặc đơn đóng, e. g
def greeting[name: str] -> str: return 'Hello ' + name
04 - Nhận xét loại không đúng chỗ sẽ bị đánh dấu là lỗi bởi trình kiểm tra loại. Nếu cần thiết, những bình luận như vậy có thể được bình luận hai lần. Ví dụ
def greeting[name: str] -> str: return 'Hello ' + name
05
Khi kiểm tra Python 2. 7, người kiểm tra loại nên coi các loại
Url = str def retry[url: Url, retry_count: int] -> None: ...64 và
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body60 là tương đương. Đối với các tham số được nhập là
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body61, các đối số thuộc loại
def greeting[name: str] -> str: return 'Hello ' + name37 cũng như
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body32 phải được chấp nhận
Trong quá trình thảo luận về các dự thảo trước đó của PEP này, nhiều ý kiến phản đối đã được đưa ra và các giải pháp thay thế đã được đề xuất. Chúng tôi thảo luận về một số trong số này ở đây và giải thích lý do tại sao chúng tôi từ chối chúng
Một số phản đối chính đã được đưa ra
Hầu hết mọi người đều quen thuộc với việc sử dụng dấu ngoặc nhọn [e. g.
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body64] bằng các ngôn ngữ như C++, Java, C# và Swift để thể hiện tham số hóa của các loại chung. Vấn đề với những thứ này là chúng thực sự khó phân tích cú pháp, đặc biệt đối với một trình phân tích cú pháp đơn giản như Python. Trong hầu hết các ngôn ngữ, sự mơ hồ thường được xử lý bằng cách chỉ cho phép các dấu ngoặc nhọn ở các vị trí cú pháp cụ thể, trong đó các biểu thức chung không được phép. [Và cũng bằng cách sử dụng các kỹ thuật phân tích cú pháp rất mạnh có thể quay lui một đoạn mã tùy ý. ]
Nhưng trong Python, chúng ta muốn các biểu thức kiểu [về mặt cú pháp] giống với các biểu thức khác, để chúng ta có thể sử dụng e. g. gán biến để tạo bí danh kiểu. Hãy xem xét biểu thức loại đơn giản này
def greeting[name: str] -> str: return 'Hello ' + name06
Từ quan điểm của trình phân tích cú pháp Python, biểu thức bắt đầu bằng bốn mã thông báo giống nhau [NAME, LESS, NAME, GREATER] dưới dạng so sánh theo chuỗi
def greeting[name: str] -> str: return 'Hello ' + name07
Chúng tôi thậm chí có thể tạo một ví dụ có thể được phân tích cú pháp theo cả hai cách
def greeting[name: str] -> str: return 'Hello ' + name08
Giả sử chúng ta có dấu ngoặc nhọn trong ngôn ngữ, điều này có thể được hiểu là một trong hai điều sau
def greeting[name: str] -> str: return 'Hello ' + name09
Chắc chắn có thể đưa ra một quy tắc để phân biệt những trường hợp như vậy, nhưng đối với hầu hết người dùng, các quy tắc sẽ cảm thấy tùy tiện và phức tạp. Nó cũng sẽ yêu cầu chúng tôi thay đổi đáng kể trình phân tích cú pháp CPython [và mọi trình phân tích cú pháp khác cho Python]. Cần lưu ý rằng trình phân tích cú pháp hiện tại của Python cố tình "câm" - một ngữ pháp đơn giản sẽ dễ dàng hơn cho người dùng suy luận về
Vì tất cả những lý do này, dấu ngoặc vuông [e. g.
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body65] là [và từ lâu đã là] cú pháp ưa thích cho các tham số kiểu chung. Chúng có thể được triển khai bằng cách xác định phương thức
def greeting[name: str] -> str: return 'Hello ' + name20 trên siêu dữ liệu và không yêu cầu cú pháp mới nào cả. Tùy chọn này hoạt động trong tất cả các phiên bản Python gần đây [bắt đầu với Python 2. 2]. Python không đơn độc trong lựa chọn cú pháp này – các lớp chung trong Scala cũng sử dụng dấu ngoặc vuông
Một dòng lập luận chỉ ra rằng PEP 3107 hỗ trợ rõ ràng việc sử dụng các biểu thức tùy ý trong chú thích hàm. Đề xuất mới sau đó được coi là không tương thích với đặc điểm kỹ thuật của PEP 3107
Phản hồi của chúng tôi về điều này là, trước hết, đề xuất hiện tại không đưa ra bất kỳ sự không tương thích trực tiếp nào, vì vậy các chương trình sử dụng chú thích trong Python 3. 4 sẽ vẫn hoạt động chính xác và không ảnh hưởng đến Python 3. 5
Chúng tôi hy vọng rằng các gợi ý kiểu cuối cùng sẽ trở thành mục đích sử dụng duy nhất cho các chú thích, nhưng điều này sẽ cần thảo luận thêm và một khoảng thời gian không dùng nữa sau lần triển khai đầu tiên của mô-đun gõ với Python 3. 5. PEP hiện tại sẽ có trạng thái tạm thời [xem PEP 411] cho đến Python 3. 6 được phát hành. Sơ đồ có thể hình dung nhanh nhất sẽ giới thiệu sự phản đối thầm lặng của các chú thích gợi ý không phải kiểu trong 3. 6, ngừng sử dụng hoàn toàn trong 3. 7 và khai báo gợi ý loại là cách sử dụng chú thích duy nhất được phép trong Python 3. 8. Điều này sẽ giúp tác giả của các gói sử dụng chú thích có nhiều thời gian để nghĩ ra cách tiếp cận khác, ngay cả khi gợi ý loại trở thành thành công chỉ sau một đêm
[CẬP NHẬT. Kể từ mùa thu năm 2017, lịch trình kết thúc trạng thái tạm thời cho PEP này và cho mô-đun
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]79 đã thay đổi, và do đó, lịch trình ngừng sử dụng chú thích khác cũng vậy. Để biết lịch trình cập nhật, xem PEP 563. ]
Một kết quả khác có thể xảy ra là các gợi ý loại cuối cùng sẽ trở thành ý nghĩa mặc định cho các chú thích, nhưng sẽ luôn có một tùy chọn để tắt chúng. Với mục đích này, đề xuất hiện tại xác định một trình trang trí
def greeting[name: str] -> str: return 'Hello ' + name23 vô hiệu hóa việc diễn giải mặc định các chú thích dưới dạng gợi ý kiểu trong một lớp hoặc hàm đã cho. Nó cũng định nghĩa một meta-decorator
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]93 có thể được sử dụng để trang trí một decorator [. ], khiến các chú thích trong bất kỳ chức năng hoặc lớp nào được trang trí bằng cái sau sẽ bị trình kiểm tra loại bỏ qua
Ngoài ra còn có
from typing import TypeVar, Iterable, Tuple T = TypeVar['T', int, float, complex] Vector = Iterable[Tuple[T, T]] def inproduct[v: Vector[T]] -> T: return sum[x*y for x, y in v] def dilate[v: Vector[T], scale: T] -> Vector[T]: return [[x * scale, y * scale] for x, y in v] vec = [] # type: Vector[float]91 nhận xét và trình kiểm tra tĩnh phải hỗ trợ các tùy chọn cấu hình để tắt kiểm tra loại trong các gói đã chọn
Bất chấp tất cả các tùy chọn này, các đề xuất đã được lưu hành để cho phép các gợi ý loại và các hình thức chú thích khác cùng tồn tại cho các đối số riêng lẻ. Một đề xuất gợi ý rằng nếu một chú thích cho một đối số nhất định là một từ điển theo nghĩa đen, thì mỗi khóa đại diện cho một dạng chú thích khác nhau và khóa
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body71 sẽ được sử dụng cho các gợi ý loại. Vấn đề với ý tưởng này và các biến thể của nó là ký hiệu trở nên rất “ồn ào” và khó đọc. Ngoài ra, trong hầu hết các trường hợp khi thư viện hiện có sử dụng chú thích, sẽ không cần kết hợp chúng với gợi ý loại. Vì vậy, cách tiếp cận đơn giản hơn để vô hiệu hóa có chọn lọc các gợi ý loại có vẻ đủ
Đề xuất hiện tại được thừa nhận là không tối ưu khi các gợi ý loại phải chứa các tham chiếu chuyển tiếp. Python yêu cầu tất cả các tên được xác định theo thời gian chúng được sử dụng. Ngoài việc nhập khẩu vòng tròn, đây hiếm khi là một vấn đề. “use” ở đây có nghĩa là “tra cứu trong thời gian chạy” và với hầu hết các tham chiếu “chuyển tiếp”, không có vấn đề gì trong việc đảm bảo rằng một tên được xác định trước khi hàm sử dụng nó được gọi
Vấn đề với các gợi ý loại là các chú thích [theo PEP 3107 và tương tự như các giá trị mặc định] được đánh giá tại thời điểm một hàm được xác định và do đó, bất kỳ tên nào được sử dụng trong một chú thích đều phải được xác định khi hàm đang được xác định. Một tình huống phổ biến là một định nghĩa lớp có các phương thức cần tham chiếu chính lớp đó trong các chú thích của chúng. [Tổng quát hơn, nó cũng có thể xảy ra với các lớp đệ quy lẫn nhau. ] Điều này là tự nhiên đối với các loại container, ví dụ
def greeting[name: str] -> str: return 'Hello ' + name10
Như đã viết, điều này sẽ không hoạt động, do tính đặc thù của Python mà các tên lớp được xác định sau khi toàn bộ nội dung của lớp đã được thực thi. Giải pháp của chúng tôi, không đặc biệt thanh lịch, nhưng đã hoàn thành công việc, là cho phép sử dụng các chuỗi ký tự trong chú thích. Mặc dù vậy, hầu hết thời gian bạn sẽ không phải sử dụng điều này – hầu hết việc sử dụng các gợi ý loại được dự kiến sẽ tham chiếu các loại dựng sẵn hoặc các loại được xác định trong các mô-đun khác
Một đề xuất ngược lại sẽ thay đổi ngữ nghĩa của các gợi ý loại để chúng hoàn toàn không được đánh giá trong thời gian chạy [xét cho cùng, việc kiểm tra loại diễn ra ngoại tuyến, vậy tại sao các gợi ý loại lại cần được đánh giá trong thời gian chạy]. Tất nhiên, điều này sẽ dẫn đến khả năng tương thích ngược, vì trình thông dịch Python không thực sự biết liệu một chú thích cụ thể có phải là một gợi ý kiểu hay không.
A compromise is possible where a
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body72 import could enable turning all annotations in a given module into string literals, as follows
def greeting[name: str] -> str: return 'Hello ' + name11
Một tuyên bố nhập khẩu
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body72 như vậy có thể được đề xuất trong một PEP riêng biệt.
[CẬP NHẬT. Tuyên bố nhập khẩu
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body72 đó và hậu quả của nó được thảo luận trong PEP 563. ]
Một số tâm hồn sáng tạo đã cố gắng phát minh ra giải pháp cho vấn đề này. Ví dụ: người ta đề xuất sử dụng dấu hai chấm [_______44_______75] cho gợi ý loại, giải quyết hai vấn đề cùng một lúc. phân biệt giữa các gợi ý loại và các chú thích khác, đồng thời thay đổi ngữ nghĩa để ngăn chặn việc đánh giá thời gian chạy. Có một số điều sai với ý tưởng này, tuy nhiên
- No thật la xâu xi. Dấu hai chấm đơn trong Python có nhiều cách sử dụng và tất cả chúng đều trông quen thuộc vì chúng giống với cách sử dụng dấu hai chấm trong văn bản tiếng Anh. Đây là một quy tắc chung mà Python tuân theo đối với hầu hết các dạng dấu chấm câu; . Nhưng việc sử dụng
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
75 này chưa từng được sử dụng trong tiếng Anh và các ngôn ngữ khác [e. g. C++], nó được sử dụng như một toán tử phạm vi, đây là một con thú rất khác. Ngược lại, dấu hai chấm đơn cho các gợi ý loại được đọc một cách tự nhiên – và không có gì lạ, vì nó được thiết kế cẩn thận cho mục đích này [ý tưởng này đã có trước PEP 3107 từ lâu]. Nó cũng được sử dụng theo cách tương tự trong các ngôn ngữ khác từ Pascal đến Swift - Bạn sẽ làm gì với các chú thích kiểu trả về?
- Đây thực sự là một tính năng mà các gợi ý loại được đánh giá trong thời gian chạy
- Tạo các gợi ý loại có sẵn trong thời gian chạy cho phép các trình kiểm tra loại thời gian chạy được xây dựng dựa trên các gợi ý loại
- Nó bắt lỗi ngay cả khi trình kiểm tra loại không chạy. Vì nó là một chương trình riêng biệt, người dùng có thể chọn không chạy nó [hoặc thậm chí cài đặt nó], nhưng vẫn có thể muốn sử dụng gợi ý loại như một dạng tài liệu ngắn gọn. Gợi ý loại bị hỏng không được sử dụng ngay cả đối với tài liệu
- Bởi vì đó là cú pháp mới, việc sử dụng dấu hai chấm cho gợi ý loại sẽ giới hạn chúng ở mã hoạt động với Python 3. 5 chỉ. Bằng cách sử dụng cú pháp hiện có, đề xuất hiện tại có thể dễ dàng hoạt động đối với các phiên bản Python 3 cũ hơn. [Và trên thực tế, mypy hỗ trợ Python 3. 2 và mới hơn. ]
- Nếu gợi ý kiểu thành công, chúng tôi có thể quyết định thêm cú pháp mới trong tương lai để khai báo kiểu cho các biến, ví dụ:
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
77. Nếu chúng ta sử dụng dấu hai chấm cho gợi ý loại đối số, để thống nhất, chúng ta phải sử dụng cùng một quy ước cho cú pháp trong tương lai, kéo dài sự xấu xí
Một vài hình thức khác của cú pháp thay thế đã được đề xuất, e. g. việc giới thiệu một từ khóa
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body78 và mệnh đề
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body79 lấy cảm hứng từ Rắn hổ mang. Nhưng tất cả đều có chung một vấn đề với dấu hai chấm. chúng sẽ không hoạt động đối với các phiên bản Python 3 cũ hơn. Điều tương tự cũng áp dụng cho lần nhập
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body72 mới
Các ý tưởng đưa ra bao gồm
- Một người trang trí, e. g.
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
81. Điều này có thể hiệu quả, nhưng nó khá dài dòng [thêm một dòng và tên đối số phải được lặp lại] và khác xa về sự tao nhã so với ký hiệu PEP 3107 - tập tin sơ khai. Chúng tôi muốn có các tệp sơ khai, nhưng chúng chủ yếu hữu ích để thêm gợi ý loại vào mã hiện có mà bản thân nó không cho phép thêm gợi ý loại, ví dụ:. g. Các gói của bên thứ 3, mã cần hỗ trợ cả Python 2 và Python 3 và đặc biệt là các mô-đun mở rộng. Đối với hầu hết các trường hợp, việc có chú thích phù hợp với định nghĩa hàm sẽ giúp chúng hữu ích hơn nhiều
- tài liệu. Hiện có một quy ước cho các chuỗi tài liệu, dựa trên ký hiệu Nhân sư [
from typing import Callable def feeder[get_next_item: Callable[[], str]] -> None: # Body def async_query[on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]] -> None: # Body
82]. This is pretty verbose [an extra line per parameter], and not very elegant. We could also make up something new, but the annotation syntax is hard to beat [because it was designed for this very purpose]
Nó cũng được đề xuất là chỉ cần đợi một bản phát hành khác. Nhưng vấn đề đó sẽ giải quyết vấn đề gì?
Bản nháp trực tiếp cho PEP này có trên GitHub. Ngoài ra còn có một trình theo dõi vấn đề, nơi diễn ra nhiều cuộc thảo luận kỹ thuật
Bản nháp trên GitHub được cập nhật thường xuyên theo từng bước nhỏ. Repo PEPS chính thức [thường] chỉ được cập nhật khi bản nháp mới được đăng lên python-dev
Tài liệu này không thể hoàn thành nếu không có những ý kiến đóng góp, khuyến khích và lời khuyên có giá trị từ Jim Baker, Jeremy Siek, Michael Matson Vitousek, Andrey Vlasovskikh, Radomir Dopieralski, Peter Ludemann, và Đại biểu BDFL, Mark Shannon
Ảnh hưởng bao gồm các ngôn ngữ, thư viện và khuôn khổ hiện có được đề cập trong PEP 482. Rất cám ơn những người tạo ra chúng, theo thứ tự bảng chữ cái. Stefan Behnel, William Edwards, Greg Ewing, Larry Hastings, Anders Hejlsberg, Alok Menghrajani, Travis E. Oliphant, Joe Pamer, Raoul-Gabriel Urma, and Julien Verlaguet