Loại không liên kết Python

Duck-typing-self là khái niệm xác định loại self một cách linh hoạt trong thời gian chạy thay vì hạn chế rằng nó phải được liên kết với loại lớp cụ thể. Trong đoạn mã trên, không có chức năng thanh nào của Foo được gọi với một đối tượng ngẫu nhiên O

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 ' + name
15 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 ' + name
16. 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 ' + name
17, được nhập từ mô-đun Python thuần túy
def greeting[name: str] -> str:
    return 'Hello ' + name
14. Ký hiệu
def greeting[name: str] -> str:
    return 'Hello ' + name
16 hoạt động trong thời gian chạy bằng cách triển khai
def greeting[name: str] -> str:
    return 'Hello ' + name
20 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 ' + name
12 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 ' + name
22 – 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 ' + name
23 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 ' + name
12. 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 ' + name
25, đố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 ' + name
25. 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 ' + name
27 ought to be annotated with
def greeting[name: str] -> str:
    return 'Hello ' + name
28. The reason for this is subtle. If
def greeting[name: str] -> str:
    return 'Hello ' + name
27 assumed a return annotation of
def greeting[name: str] -> str:
    return 'Hello ' + name
28, would that mean that an argument-less, un-annotated
def greeting[name: str] -> str:
    return 'Hello ' + name
27 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 ' + name
27 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 ' + name
33,
def greeting[name: str] -> str:
    return 'Hello ' + name
34 and
def greeting[name: str] -> str:
    return 'Hello ' + name
35

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 ' + name
36 argument is
def greeting[name: str] -> str:
    return 'Hello ' + name
37. Analogically, the expected return type is
def greeting[name: str] -> str:
    return 'Hello ' + name
37

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 ' + name
39 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 ' + name
40,
def greeting[name: str] -> str:
    return 'Hello ' + name
12,
def greeting[name: str] -> str:
    return 'Hello ' + name
42,
def greeting[name: str] -> str:
    return 'Hello ' + name
43,
def greeting[name: str] -> str:
    return 'Hello ' + name
44, all ABCs and stand-ins for concrete classes exported from
def greeting[name: str] -> str:
    return 'Hello ' + name
14 [e. g.
def greeting[name: str] -> str:
    return 'Hello ' + name
17 and
def greeting[name: str] -> str:
    return 'Hello ' + name
47], 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 ' + name
12 and
def greeting[name: str] -> str:
    return 'Hello ' + name
42] are available in the
def greeting[name: str] -> str:
    return 'Hello ' + name
14 module

When used in a type hint, the expression

def greeting[name: str] -> str:
    return 'Hello ' + name
40 is considered equivalent to
def greeting[name: str] -> str:
    return 'Hello ' + name
52

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 ' + name
53. 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 ' + name
44. 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 ' + name
55 does double-duty as a replacement for
def greeting[name: str] -> str:
    return 'Hello ' + name
56,
def greeting[name: str] -> str:
    return 'Hello ' + name
57 is implemented by deferring to
def greeting[name: str] -> str:
    return 'Hello ' + name
58. However,
def greeting[name: str] -> str:
    return 'Hello ' + name
59 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 ' + name
14 called
def greeting[name: str] -> str:
    return 'Hello ' + name
61. 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 ' + name
62 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 ' + name
62 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 ' + name
61 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 ' + name
37 và
def greeting[name: str] -> str:
    return 'Hello ' + name
66. 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 ' + name
67 có thể được gọi với hai đối số
def greeting[name: str] -> str:
    return 'Hello ' + name
37 hoặc hai đối số
def greeting[name: str] -> str:
    return 'Hello ' + name
66, 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 ' + name
37 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 ' + name
0

Cuộc gọi hợp lệ nhưng biến loại

def greeting[name: str] -> str:
    return 'Hello ' + name
72 sẽ được đặt thành
def greeting[name: str] -> str:
    return 'Hello ' + name
37 chứ không phải
def greeting[name: str] -> str:
    return 'Hello ' + name
74. 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 ' + name
75 cũng sẽ là
def greeting[name: str] -> str:
    return 'Hello ' + name
37

Ngoài ra,

def greeting[name: str] -> str:
    return 'Hello ' + name
12 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 ' + name
1

Đ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 ' + name
78

Bạn có thể bao gồm một lớp cơ sở

def greeting[name: str] -> str:
    return 'Hello ' + name
79 để đị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 ' + name
2

def greeting[name: str] -> str:
    return 'Hello ' + name
80 làm lớp cơ sở định nghĩa rằng lớp
def greeting[name: str] -> str:
    return 'Hello ' + name
81 nhận một tham số kiểu duy nhất là
def greeting[name: str] -> str:
    return 'Hello ' + name
82. Điều này cũng làm cho
def greeting[name: str] -> str:
    return 'Hello ' + name
82 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 ' + name
79 sử dụng một siêu dữ liệu xác định
def greeting[name: str] -> str:
    return 'Hello ' + name
85 để
def greeting[name: str] -> str:
    return 'Hello ' + name
86 hợp lệ như một loại

def greeting[name: str] -> str:
    return 'Hello ' + name
3

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 ' + name
4

Mỗi đối số biến loại cho

def greeting[name: str] -> str:
    return 'Hello ' + name
79 phải khác biệt. Điều này là không hợp lệ

def greeting[name: str] -> str:
    return 'Hello ' + name
5

Lớp cơ sở

def greeting[name: str] -> str:
    return 'Hello ' + name
80 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 ' + name
6

Định nghĩa lớp đó tương đương với

def greeting[name: str] -> str:
    return 'Hello ' + name
7

Bạn có thể sử dụng đa thừa kế với

def greeting[name: str] -> str:
    return 'Hello ' + name
79

def greeting[name: str] -> str:
    return 'Hello ' + name
8

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 ' + name
91 không phải là chung chung nhưng hoàn toàn kế thừa từ
def greeting[name: str] -> str:
    return 'Hello ' + name
92

def greeting[name: str] -> str:
    return 'Hello ' + name
9

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 ' + name
93 kế thừa từ
def greeting[name: str] -> str:
    return 'Hello ' + name
80

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 ' + name
93, bạn gọi
def greeting[name: str] -> str:
    return 'Hello ' + name
96 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 ' + name
93. 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 ' + name
99] sử dụng
def greeting[name: str] -> str:
    return 'Hello ' + name
82 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 ' + name
12 đượ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 ' + name
93 –
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 ' + name
17 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 ' + name
47,
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 ' + name
80 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 ' + name
47 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 ' + name
82 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 ' + name
82 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 ' + name
79 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 ' + name
72 đượ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 ' + name
14 đề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 ' + name
17]. 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 ' + name
42. 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 ' + name
40 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 ' + name
40 đã đượ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 ' + name
40, 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 ' + name
40 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:
    # Body
0

Để 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 ' + name
42 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:
    # Body
1

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 ' + name
75 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:
    # Body
2

Một loại đặc biệt của loại là

def greeting[name: str] -> str:
    return 'Hello ' + name
12. Mọi loại đều nhất quán với
def greeting[name: str] -> str:
    return 'Hello ' + name
12. It can be considered a type that has all values and all methods. Note that
def greeting[name: str] -> str:
    return 'Hello ' + name
12 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 ' + name
12, the type checker will allow all operations on it, and a value of type
def greeting[name: str] -> str:
    return 'Hello ' + name
12 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 ' + name
12. 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 ' + name
12

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
3

Quy tắc này cũng áp dụng cho

def greeting[name: str] -> str:
    return 'Hello ' + name
43, 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 ' + name
44 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 ' + name
56

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
4

Mô-đun

def greeting[name: str] -> str:
    return 'Hello ' + name
14 cung cấp một loại đặc biệt
def greeting[name: str] -> str:
    return 'Hello ' + name
13 để 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:
    # Body
5

Chú thích

def greeting[name: str] -> str:
    return 'Hello ' + name
13 đượ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 ' + name
13 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:
    # Body
6

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:
    # Body
7

Loại

def greeting[name: str] -> str:
    return 'Hello ' + name
13 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:
    # Body
8

Đô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:
    # Body
9

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]:
    # Body
0

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]:
    # Body
1

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]:
    # Body
2

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]:
    # Body
3

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]:
    # Body
4

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]:
    # Body
5

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 ' + name
82 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 ' + name
43 hoặc
def greeting[name: str] -> str:
    return 'Hello ' + name
44 đề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 ' + name
12

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]:
    # Body
6

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]:
    # Body
7

Đ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]:
    # Body
8

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]:
    # Body
9

Đừ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 ' + name
14 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 ' + name
15 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 ' + name
40 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 ' + name
40]. 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 ' + name
37 và chỉ suy ra
Url = str

def retry[url: Url, retry_count: int] -> None: ...
94 hoặc
def greeting[name: str] -> str:
    return 'Hello ' + name
12, 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 ' + name
75 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 ' + name
42, 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 ' + name
14 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 đươ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]]
    
    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ẫ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]]
    
    32 mới được xuất, tôi. e. tên trước và sau
    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]]
    
    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 sau

    from typing import Sequence, TypeVar
    
    T = TypeVar['T']      # Declare type variable
    
    def first[l: Sequence[T]] -> T:   # Generic function
        return l[0]
    
    9

    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]]
    
    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ặ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]]
    
    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ủ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]]
    
    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
    
    0

    Do đó, 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 ' + name
20 của loại
def greeting[name: str] -> str:
    return 'Hello ' + name
66 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 + y
1

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 + y
2

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 + y
3

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 + y
4

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 + y
5

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 ' + name
61 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 + y
6

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 ' + name
72 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 + y
7

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 + y
8

[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 ' + name
14

It defines the fundamental building blocks for constructing types [e. g.

def greeting[name: str] -> str:
    return 'Hello ' + name
12], 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 ' + name
17], and a small collection of convenience definitions

Note that special type constructs, such as

def greeting[name: str] -> str:
    return 'Hello ' + name
12,
def greeting[name: str] -> str:
    return 'Hello ' + name
42, and type variables defined using
def greeting[name: str] -> str:
    return 'Hello ' + name
61 are only supported in the type annotation context, and
def greeting[name: str] -> str:
    return 'Hello ' + name
79 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 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]]
    
    92. Arbitrary-length homogeneous tuples can be expressed using one type and ellipsis, 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]]
    
    93. [The
    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]]
    
    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 of
    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]]
    
    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 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:
        # 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 ' + name
47,
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
05,
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 ' + name
17 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:
    # Body
02

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ủ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:
        # 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ức
    Url = 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ô-đun
    def 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:
    # Body
21 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:
    # Body
22]

  • 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, 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:
        # 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ớ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
    
    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ư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]
    
    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:
    # Body
44

  • 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ên
    def 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:
    # Body
48. 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 + y
9

tương đương như sau

def greeting[name: str] -> str:
    return 'Hello ' + name
00

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:
    # Body
49

Đố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 ' + name
01

Đô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 ' + name
02

Đô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:
    # Body
48 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:
    # Body
48 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:
    # Body
48 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 ' + name
03

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ệ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]
    
    69 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]
    
    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:
    # Body
60 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:
    # Body
61, các đối số thuộc loại
def greeting[name: str] -> str:
    return 'Hello ' + name
37 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:
    # Body
32 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:
    # Body
64] 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 ' + name
06

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 ' + name
07

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 ' + name
08

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 ' + name
09

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:
    # Body
65] 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 ' + name
20 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 ' + name
23 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:
    # Body
71 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 ' + name
10

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:
    # Body
72 import could enable turning all annotations in a given module into string literals, as follows

def greeting[name: str] -> str:
    return 'Hello ' + name
11

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:
    # Body
72 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:
    # Body
72 đó 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:
    # Body
78 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:
    # Body
79 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:
    # Body
72 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

Không liên kết có nghĩa là gì trong Python?

Một ký hiệu chưa được gán giá trị khi gán hoặc trong lệnh gọi hàm được gọi là "không liên kết. ”

Why is variable unbound Python?

Lỗi cục bộ không liên kết xảy ra khi một biến cục bộ được tham chiếu trước khi nó được gán . Các biến trong Python chỉ được chỉ định bên trong một hàm toàn cục theo mặc định. Nếu một giá trị được gán cho một biến trong thân hàm, trừ khi nó được xác định rõ ràng là toàn cục, thì nó được coi là cục bộ.

Sự khác biệt giữa các phương thức ràng buộc và không ràng buộc là gì?

Phương thức không liên kết về cơ bản là một hàm với một số phần bổ sung. 'Phương thức ràng buộc' được gọi như vậy vì đối số đầu tiên [tức là self ] đã được đặt thành ; . fred[10] [điều này thực sự cần thiết dựa trên cách thức hoạt động của CPython].

What is an unbound function?

Bây giờ, hàm số không bị chặn trên hoặc dưới bởi một giới hạn hữu hạn được gọi là hàm không bị chặn. Ví dụ. - x là một hàm không bị chặn vì nó suy rộng từ −∞ đến ∞.

Chủ Đề