- Trạng thái
- Thông báo cho người đánh giá
- trừu tượng
- Cơ sở lý luận
- Non-goals
- Sự chỉ rõ
- Chú thích biến toàn cầu và địa phương
- Chú thích biến lớp và phiên bản
- Chú thích biểu thức
- Nơi chú thích aren cho phép
- Chú thích biến trong các tệp sơ khai
- Kiểu mã hóa ưa thích cho các chú thích thay đổi
- Thay đổi đối với thư viện và tài liệu tiêu chuẩn
- Hiệu ứng thời gian chạy của các chú thích loại
- Các công dụng khác của chú thích
- Các đề xuất bị từ chối/hoãn lại
- Khả năng tương thích ngược
- Thực hiện
- Bản quyền
Trạng thái
Thông báo cho người đánh giá
Thông báo cho người đánh giá
trừu tượng
Cơ sở lý luận
Sự chỉ rõ
trừu tượng
Cơ sở lý luận
# 'primes' is a list of integers primes = [] # type: List[int] # 'captain' is a string [Note: initial value is a problem] captain = ... # type: str class Starship: # 'stats' is a class variable stats = {} # type: Dict[str, int]
Sự chỉ rõ
primes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}
Chú thích biến toàn cầu và địa phương
Cơ sở lý luận
Sự chỉ rõ
- Chú thích biến toàn cầu và địa phương
- Chú thích biến lớp và phiên bản
- Chú thích biểu thức
if some_value: my_var = function[] # type: Logger else: my_var = another_function[] # Why isn't there a type here?
- Nơi chú thích aren cho phép
- Chú thích biến trong các tệp sơ khai
- Kiểu mã hóa ưa thích cho các chú thích thay đổi
path = None # type: Optional[str] # Path to module source
- Thay đổi đối với thư viện và tài liệu tiêu chuẩn
Hiệu ứng thời gian chạy của các chú thích loại
Non-goals
Các công dụng khác của chú thích
Các đề xuất bị từ chối/hoãn lạiPython will remain a dynamically typed language, and the authors have no desire to ever make type hints mandatory, even by convention. Type annotations should not be confused with variable declarations in statically typed languages. The goal of annotation syntax is to provide an easy way to specify structured type metadata for third party tools.
Khả năng tương thích ngược
Sự chỉ rõ
Chú thích biến toàn cầu và địa phương
my_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.
Chú thích biến lớp và phiên bản
var = value # type: annotation var: annotation; var = value var: annotation = value
Chú thích biểu thức
Nơi chú thích aren cho phép
Chú thích biến toàn cầu và địa phương
Các loại người dân địa phương và toàn cầu có thể được chú thích như sau:
some_number: int # variable without initial value some_list: List[int] = [] # variable with initial value
Có thể bỏ qua giá trị ban đầu cho phép gõ các biến dễ dàng hơn được gán trong các nhánh có điều kiện:
sane_world: bool if 2+2 == 4: sane_world = True else: sane_world = False
Lưu ý rằng, mặc dù cú pháp không cho phép đóng gói tple, nhưng nó không cho phép người ta chú thích các loại biến khi sử dụng việc giải nén tuple:
# Tuple packing with variable annotation syntax t: Tuple[int, ...] = [1, 2, 3] # or t: Tuple[int, ...] = 1, 2, 3 # This only works in Python 3.8+ # Tuple unpacking with variable annotation syntax header: str kind: int body: Optional[List[str]] header, kind, body = message
Bỏ qua giá trị ban đầu để lại biến không chính xác:
a: int print[a] # raises NameError
Tuy nhiên, việc chú thích một biến cục bộ sẽ khiến thông dịch viên luôn biến nó thành một địa phương:
primes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}0
Như thể mã là:
primes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}1
Chú thích loại trùng lặp sẽ bị bỏ qua. Tuy nhiên, trình kiểm tra loại tĩnh có thể đưa ra cảnh báo cho các chú thích của cùng một biến theo một loại khác:
primes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}2
Chú thích biến lớp và phiên bản
Các chú thích loại cũng có thể được sử dụng để chú thích các biến lớp và thể hiện trong các cơ quan và phương pháp lớp. Cụ thể, ký hiệu không có giá trị
path = None # type: Optional[str] # Path to module source8 cho phép người ta chú thích các biến thể hiện nên được khởi tạo trong
path = None # type: Optional[str] # Path to module source9 hoặc
my_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.0. Cú pháp được đề xuất như sau:
primes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}3
Ở đây
my_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.1 là một lớp đặc biệt được xác định bởi mô -đun gõ cho biết trình kiểm tra loại tĩnh rằng biến này không nên được đặt trên các trường hợp.
Lưu ý rằng tham số
my_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.1 không thể bao gồm bất kỳ biến loại nào, bất kể mức độ lồng nhau:
my_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.3 và
my_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.4 đều không hợp lệ nếu
my_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.5 là biến loại.
Điều này có thể được minh họa với một ví dụ chi tiết hơn. Trong lớp học này:
primes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}4
my_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.6 được dự định là một biến lớp [theo dõi nhiều số liệu thống kê trên mỗi trò chơi khác nhau], trong khi
my_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.7 là một biến thể hiện với giá trị mặc định được đặt trong lớp. Sự khác biệt này có thể không được nhìn thấy bởi một trình kiểm tra loại: cả hai đều được khởi tạo trong lớp, nhưng
my_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.7 chỉ đóng vai trò là giá trị mặc định thuận tiện cho biến thể hiện, trong khi
my_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.6 thực sự là một biến lớp - nó được dự định sẽ được chia sẻ bởi tất cả các trường hợp.
Vì cả hai biến xảy ra được khởi tạo ở cấp độ lớp, nên rất hữu ích khi phân biệt chúng bằng cách đánh dấu các biến lớp là chú thích với các loại được bọc trong
var = value # type: annotation var: annotation; var = value var: annotation = value0. Theo cách này, một trình kiểm tra loại có thể gắn cờ các bài tập tình cờ vào các thuộc tính có cùng tên trên các trường hợp.
Ví dụ, chú thích lớp đã thảo luận:
primes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}5
Như một vấn đề thuận tiện [và quy ước], các biến thể hiện có thể được chú thích trong
path = None # type: Optional[str] # Path to module source9 hoặc các phương thức khác, thay vì trong lớp:
primes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}6
Chú thích biểu thức
Mục tiêu của chú thích có thể là bất kỳ mục tiêu gán duy nhất hợp lệ nào, ít nhất là về mặt cú pháp [tùy thuộc vào kiểu kiểm tra loại phải làm gì với điều này]:
primes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}7
Lưu ý rằng ngay cả một tên ngoặc cũng được coi là một biểu thức, không phải là một tên đơn giản:
primes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}8
Nơi chú thích aren cho phép
Việc cố gắng chú thích các biến theo
var = value # type: annotation var: annotation; var = value var: annotation = value2 hoặc
var = value # type: annotation var: annotation; var = value var: annotation = value3 là bất hợp pháp trong cùng một phạm vi chức năng:
primes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}9
Lý do là các biến riêng của
var = value # type: annotation var: annotation; var = value var: annotation = value2 và
var = value # type: annotation var: annotation; var = value var: annotation = value3 don don; Do đó, các chú thích loại thuộc về phạm vi sở hữu biến.
Chỉ được phép cho phép các mục tiêu gán đơn và các giá trị bên tay phải duy nhất được cho phép. Ngoài ra, người ta không thể chú thích các biến được sử dụng trong câu lệnh
var = value # type: annotation var: annotation; var = value var: annotation = value6 hoặc
var = value # type: annotation var: annotation; var = value var: annotation = value7; Chúng có thể được chú thích trước thời hạn, theo cách tương tự như giải nén:
if some_value: my_var = function[] # type: Logger else: my_var = another_function[] # Why isn't there a type here?0
Chú thích biến trong các tệp sơ khai
Vì các chú thích thay đổi dễ đọc hơn các bình luận loại, chúng được ưa thích trong các tệp sơ khai cho tất cả các phiên bản của Python, bao gồm Python 2.7. Lưu ý rằng các tệp sơ khai không được thực thi bởi các phiên dịch viên Python và do đó sử dụng các chú thích thay đổi sẽ không dẫn đến lỗi. Kiểu kiểm tra loại nên hỗ trợ các chú thích thay đổi trong các cuống cho tất cả các phiên bản của Python. Ví dụ:
if some_value: my_var = function[] # type: Logger else: my_var = another_function[] # Why isn't there a type here?1
Kiểu mã hóa ưa thích cho các chú thích thay đổi
Chú thích cho các biến cấp mô -đun, các biến lớp và thể hiện và các biến cục bộ phải có một không gian duy nhất sau khi đại tràng tương ứng. Không nên có không gian trước đại tràng. Nếu một nhiệm vụ có phía bên tay phải, thì dấu hiệu bình đẳng sẽ có chính xác một khoảng trống ở cả hai bên. Ví dụ:
- Đúng:
if some_value: my_var = function[] # type: Logger else: my_var = another_function[] # Why isn't there a type here?
2 - No:
if some_value: my_var = function[] # type: Logger else: my_var = another_function[] # Why isn't there a type here?
3
Thay đổi đối với thư viện và tài liệu tiêu chuẩn
- Một loại đồng biến mới
var = value # type: annotation var: annotation; var = value var: annotation = value
8 được thêm vào mô -đunvar = value # type: annotation var: annotation; var = value var: annotation = value
9. Nó chỉ chấp nhận một đối số duy nhất phải là một loại hợp lệ và được sử dụng để chú thích các biến lớp không nên được đặt trên các phiên bản lớp. Hạn chế này được đảm bảo bởi các trình kiểm tra tĩnh, nhưng không phải là thời gian chạy. Xem phần Classvar để biết các ví dụ và giải thích về việc sử dụngmy_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.
1 và xem phần bị từ chối để biết thêm thông tin về lý do đằng saumy_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.
1. - Chức năng
some_number: int # variable without initial value some_list: List[int] = [] # variable with initial value
2 Trong mô -đunvar = value # type: annotation var: annotation; var = value var: annotation = value
9 sẽ được mở rộng, để người ta có thể truy xuất các chú thích loại khi chạy từ các mô -đun và các lớp cũng như các chức năng. Các chú thích được trả về dưới dạng ánh xạ từ điển từ biến hoặc đối số cho các gợi ý loại của chúng với các tài liệu tham khảo phía trước được đánh giá. Đối với các lớp, nó trả về một ánh xạ [có lẽsome_number: int # variable without initial value some_list: List[int] = [] # variable with initial value
4] được xây dựng từ các chú thích theo thứ tự phân giải phương thức. - Các hướng dẫn được đề xuất để sử dụng các chú thích sẽ được thêm vào tài liệu, chứa một bản tóm tắt sư phạm về các thông số kỹ thuật được mô tả trong PEP này và trong PEP 484. Ngoài ra, một tập lệnh trợ giúp để dịch các nhận xét loại thành các chú thích loại sẽ được xuất bản với thư viện tiêu chuẩn.
Hiệu ứng thời gian chạy của các chú thích loại
Chú thích một biến cục bộ sẽ khiến thông dịch viên coi nó như một địa phương, ngay cả khi nó không bao giờ được chỉ định. Chú thích cho các biến cục bộ sẽ không được đánh giá:
if some_value: my_var = function[] # type: Logger else: my_var = another_function[] # Why isn't there a type here?4
Tuy nhiên, nếu nó ở cấp độ mô -đun hoặc lớp, thì loại sẽ được đánh giá:
if some_value: my_var = function[] # type: Logger else: my_var = another_function[] # Why isn't there a type here?5
Ngoài ra, ở cấp độ mô -đun hoặc lớp, nếu mục được chú thích là một tên đơn giản, thì nó và chú thích sẽ được lưu trữ trong thuộc tính
some_number: int # variable without initial value some_list: List[int] = [] # variable with initial value5 của mô -đun hoặc lớp đó Chú thích. Đây là một ví dụ:
if some_value: my_var = function[] # type: Logger else: my_var = another_function[] # Why isn't there a type here?6
some_number: int # variable without initial value some_list: List[int] = [] # variable with initial value5 có thể ghi, vì vậy điều này được cho phép:
if some_value: my_var = function[] # type: Logger else: my_var = another_function[] # Why isn't there a type here?7
Nhưng việc cố gắng cập nhật
some_number: int # variable without initial value some_list: List[int] = [] # variable with initial value5 lên một cái gì đó không phải là ánh xạ được đặt hàng có thể dẫn đến một kiểu mẫu:
if some_value: my_var = function[] # type: Logger else: my_var = another_function[] # Why isn't there a type here?8
.
Cách khuyến nghị để nhận được các chú thích trong thời gian chạy là sử dụng hàm
path = None # type: Optional[str] # Path to module source7; Như với tất cả các thuộc tính Dunder, bất kỳ việc sử dụng
some_number: int # variable without initial value some_list: List[int] = [] # variable with initial value5 nào không bị phá vỡ mà không cần cảnh báo:
if some_value: my_var = function[] # type: Logger else: my_var = another_function[] # Why isn't there a type here?9
Lưu ý rằng nếu các chú thích không được tìm thấy thống kê, thì từ điển
some_number: int # variable without initial value some_list: List[int] = [] # variable with initial value5 hoàn toàn không được tạo ra. Ngoài ra, giá trị của việc có các chú thích có sẵn tại địa phương không bù đắp chi phí phải tạo và điền từ điển chú thích trên mỗi cuộc gọi chức năng. Do đó, các chú thích ở cấp độ chức năng không được đánh giá và không được lưu trữ.
Các công dụng khác của chú thích
Trong khi Python với PEP này sẽ không phản đối:
path = None # type: Optional[str] # Path to module source0
Vì nó sẽ không quan tâm đến việc chú thích loại ngoài phạm vi đánh giá mà không cần nâng cao, một trình kiểm tra loại gặp phải nó sẽ gắn cờ nó, trừ khi bị vô hiệu hóa với
sane_world: bool if 2+2 == 4: sane_world = True else: sane_world = False3 hoặc
sane_world: bool if 2+2 == 4: sane_world = True else: sane_world = False4.
Tuy nhiên, vì Python đã giành được sự chăm sóc của loại hình này là gì, nếu đoạn trích ở trên ở cấp độ toàn cầu hoặc trong một lớp,
some_number: int # variable without initial value some_list: List[int] = [] # variable with initial value5 sẽ bao gồm
sane_world: bool if 2+2 == 4: sane_world = True else: sane_world = False6.
Những chú thích được lưu trữ này có thể được sử dụng cho các mục đích khác, nhưng với PEP này, chúng tôi đề xuất rõ ràng gợi ý loại là việc sử dụng các chú thích ưa thích.
Các đề xuất bị từ chối/hoãn lại
- Chúng ta có nên giới thiệu các chú thích thay đổi ở tất cả không? Các chú thích thay đổi đã có từ gần hai năm dưới dạng nhận xét loại, bị PEP 484. Chúng được sử dụng rộng rãi bởi các trình kiểm tra loại bên thứ ba [MyPy, PyType, Pycharm, v.v.] và bởi các dự án sử dụng trình kiểm tra loại. Tuy nhiên, cú pháp nhận xét có nhiều nhược điểm được liệt kê trong Rationale. PEP này không phải là về sự cần thiết của các chú thích loại, mà là về những gì nên là cú pháp cho các chú thích như vậy. Variable annotations have already been around for almost two years in the form of type comments, sanctioned by PEP 484. They are extensively used by third party type checkers [mypy, pytype, PyCharm, etc.] and by projects using the type checkers. However, the comment syntax has many downsides listed in Rationale. This PEP is not about the need for type annotations, it is about what should be the syntax for such annotations.
- Giới thiệu một từ khóa mới: Việc lựa chọn từ khóa tốt là khó, ví dụ: Nó có thể là
sane_world: bool if 2+2 == 4: sane_world = True else: sane_world = False
7 bởi vì đó là một tên biến quá phổ biến và nó có thể làsane_world: bool if 2+2 == 4: sane_world = True else: sane_world = False
8 nếu chúng ta muốn sử dụng nó cho các biến hoặc toàn cầu của lớp. Thứ hai, bất kể chúng tôi chọn gì, chúng tôi vẫn cần nhậpsane_world: bool if 2+2 == 4: sane_world = True else: sane_world = False
9. The choice of a good keyword is hard, e.g. it can’t besane_world: bool if 2+2 == 4: sane_world = True else: sane_world = False
7 because that is way too common a variable name, and it can’t besane_world: bool if 2+2 == 4: sane_world = True else: sane_world = False
8 if we want to use it for class variables or globals. Second, no matter what we choose, we’d still need asane_world: bool if 2+2 == 4: sane_world = True else: sane_world = False
9 import. - Sử dụng
# Tuple packing with variable annotation syntax t: Tuple[int, ...] = [1, 2, 3] # or t: Tuple[int, ...] = 1, 2, 3 # This only works in Python 3.8+ # Tuple unpacking with variable annotation syntax header: str kind: int body: Optional[List[str]] header, kind, body = message
0 làm từ khóa: Đề xuất sẽ là:# Tuple packing with variable annotation syntax t: Tuple[int, ...] = [1, 2, 3] # or t: Tuple[int, ...] = 1, 2, 3 # This only works in Python 3.8+ # Tuple unpacking with variable annotation syntax header: str kind: int body: Optional[List[str]] header, kind, body = message
0 as a keyword: The proposal would be:path = None # type: Optional[str] # Path to module source
1Vấn đề với điều này là
# Tuple packing with variable annotation syntax t: Tuple[int, ...] = [1, 2, 3] # or t: Tuple[int, ...] = 1, 2, 3 # This only works in Python 3.8+ # Tuple unpacking with variable annotation syntax header: str kind: int body: Optional[List[str]] header, kind, body = message
0 có nghĩa là xác định chức năng của một thế hệ lập trình viên Python [và công cụ!], Và cũng sử dụng nó để xác định các biến không làm tăng độ rõ. [Mặc dù điều này tất nhiên là chủ quan.] - Sử dụng cú pháp dựa trên chức năng: Nó đã được đề xuất để chú thích các loại biến bằng cách sử dụng
# Tuple packing with variable annotation syntax t: Tuple[int, ...] = [1, 2, 3] # or t: Tuple[int, ...] = 1, 2, 3 # This only works in Python 3.8+ # Tuple unpacking with variable annotation syntax header: str kind: int body: Optional[List[str]] header, kind, body = message
2. Mặc dù cú pháp này làm giảm bớt một số vấn đề với các nhận xét loại như không có chú thích trong AST, nhưng nó không giải quyết các vấn đề khác như khả năng đọc và nó giới thiệu chi phí thời gian chạy có thể.: It was proposed to annotate types of variables using# Tuple packing with variable annotation syntax t: Tuple[int, ...] = [1, 2, 3] # or t: Tuple[int, ...] = 1, 2, 3 # This only works in Python 3.8+ # Tuple unpacking with variable annotation syntax header: str kind: int body: Optional[List[str]] header, kind, body = message
2. Although this syntax alleviates some problems with type comments like absence of the annotation in AST, it does not solve other problems such as readability and it introduces possible runtime overhead. - Cho phép các chú thích loại để giải nén tuple: Điều này gây ra sự mơ hồ: Nó không rõ câu nói này có nghĩa là gì: This causes ambiguity: it’s not clear what this statement means:
Có phải
# Tuple packing with variable annotation syntax t: Tuple[int, ...] = [1, 2, 3] # or t: Tuple[int, ...] = 1, 2, 3 # This only works in Python 3.8+ # Tuple unpacking with variable annotation syntax header: str kind: int body: Optional[List[str]] header, kind, body = message
3 và# Tuple packing with variable annotation syntax t: Tuple[int, ...] = [1, 2, 3] # or t: Tuple[int, ...] = 1, 2, 3 # This only works in Python 3.8+ # Tuple unpacking with variable annotation syntax header: str kind: int body: Optional[List[str]] header, kind, body = message
4 cả hai loạimy_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.
5, hay chúng ta mong đợimy_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.
5 sẽ là một loại hai mặt hàng được phân phối trên# Tuple packing with variable annotation syntax t: Tuple[int, ...] = [1, 2, 3] # or t: Tuple[int, ...] = 1, 2, 3 # This only works in Python 3.8+ # Tuple unpacking with variable annotation syntax header: str kind: int body: Optional[List[str]] header, kind, body = message
3 và# Tuple packing with variable annotation syntax t: Tuple[int, ...] = [1, 2, 3] # or t: Tuple[int, ...] = 1, 2, 3 # This only works in Python 3.8+ # Tuple unpacking with variable annotation syntax header: str kind: int body: Optional[List[str]] header, kind, body = message
4, hoặc có lẽ# Tuple packing with variable annotation syntax t: Tuple[int, ...] = [1, 2, 3] # or t: Tuple[int, ...] = 1, 2, 3 # This only works in Python 3.8+ # Tuple unpacking with variable annotation syntax header: str kind: int body: Optional[List[str]] header, kind, body = message
3 có loạia: int print[a] # raises NameError
0 và# Tuple packing with variable annotation syntax t: Tuple[int, ...] = [1, 2, 3] # or t: Tuple[int, ...] = 1, 2, 3 # This only works in Python 3.8+ # Tuple unpacking with variable annotation syntax header: str kind: int body: Optional[List[str]] header, kind, body = message
4 có loại ____ không? . - Hình thức được đặt ra
a: int print[a] # raises NameError
3 cho các chú thích: Nó được đưa lên trên Python-Ideas như một phương thuốc cho sự mơ hồ được đề cập ở trên, nhưng nó đã bị từ chối vì cú pháp như vậy sẽ là lông, lợi ích rất nhẹ và khả năng đọc sẽ kém.a: int print[a] # raises NameError
3 for annotations: It was brought up on python-ideas as a remedy for the above-mentioned ambiguity, but it was rejected since such syntax would be hairy, the benefits are slight, and the readability would be poor. - Cho phép chú thích trong các bài tập bị chuỗi: Điều này có vấn đề về sự mơ hồ và khả năng đọc tương tự như việc giải nén Tuple, ví dụ: trong: This has problems of ambiguity and readability similar to tuple unpacking, for example in:
path = None # type: Optional[str] # Path to module source
2Đó là mơ hồ, các loại của
# Tuple packing with variable annotation syntax t: Tuple[int, ...] = [1, 2, 3] # or t: Tuple[int, ...] = 1, 2, 3 # This only works in Python 3.8+ # Tuple unpacking with variable annotation syntax header: str kind: int body: Optional[List[str]] header, kind, body = message
4 vàa: int print[a] # raises NameError
5 nên là gì? Ngoài ra dòng thứ hai rất khó phân tích. - Cho phép các chú thích trong tuyên bố
var = value # type: annotation var: annotation; var = value var: annotation = value
7 vàvar = value # type: annotation var: annotation; var = value var: annotation = value
6: Điều này đã bị từ chối vì trongvar = value # type: annotation var: annotation; var = value var: annotation = value
6, nó sẽ khiến cho việc phát hiện ra một điều không thể thực tế, và trongvar = value # type: annotation var: annotation; var = value var: annotation = value
7, nó sẽ nhầm lẫn trình phân tích cú pháp Cpython LL LL [1].var = value # type: annotation var: annotation; var = value var: annotation = value
7 andvar = value # type: annotation var: annotation; var = value var: annotation = value
6 statement: This was rejected because invar = value # type: annotation var: annotation; var = value var: annotation = value
6 it would make it hard to spot the actual iterable, and invar = value # type: annotation var: annotation; var = value var: annotation = value
7 it would confuse the CPython’s LL[1] parser. - Đánh giá các chú thích cục bộ theo thời gian định nghĩa chức năng: Điều này đã bị Guido từ chối vì vị trí của chú thích cho thấy mạnh mẽ rằng nó trong cùng phạm vi với mã xung quanh. This has been rejected by Guido because the placement of the annotation strongly suggests that it’s in the same scope as the surrounding code.
- Lưu trữ các chú thích biến cũng trong phạm vi chức năng: Giá trị của việc có sẵn các chú thích tại địa phương là không đủ để bù đắp đáng kể chi phí tạo và điền từ điển trên mỗi cuộc gọi chức năng. The value of having the annotations available locally is just not enough to significantly offset the cost of creating and populating the dictionary on each function call.
- Khởi tạo các biến được chú thích mà không cần gán: Nó đã được đề xuất trên các iDeas Python để khởi tạo
# Tuple packing with variable annotation syntax t: Tuple[int, ...] = [1, 2, 3] # or t: Tuple[int, ...] = 1, 2, 3 # This only works in Python 3.8+ # Tuple unpacking with variable annotation syntax header: str kind: int body: Optional[List[str]] header, kind, body = message
3 trongprimes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}
01 đếnpath = None # type: Optional[str] # Path to module source
4 hoặc cho một hằng số đặc biệt bổ sung như JavaScript tựaprimes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}
03. Tuy nhiên, việc thêm một giá trị singleton khác vào ngôn ngữ sẽ cần phải được kiểm tra ở mọi nơi trong mã. Do đó, Guido chỉ nói rõ ràng về điều này. It was proposed on python-ideas to initialize# Tuple packing with variable annotation syntax t: Tuple[int, ...] = [1, 2, 3] # or t: Tuple[int, ...] = 1, 2, 3 # This only works in Python 3.8+ # Tuple unpacking with variable annotation syntax header: str kind: int body: Optional[List[str]] header, kind, body = message
3 inprimes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}
01 topath = None # type: Optional[str] # Path to module source
4 or to an additional special constant like Javascript’sprimes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}
03. However, adding yet another singleton value to the language would needed to be checked for everywhere in the code. Therefore, Guido just said plain “No” to this. - Thêm cũng
primes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}
04 vào mô -đun gõ: Điều này là dự phòng vì các biến thể hiện là cách phổ biến hơn các biến lớp. Việc sử dụng phổ biến hơn xứng đáng là mặc định.primes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}
04 to the typing module: This is redundant because instance variables are way more common than class variables. The more common usage deserves to be the default. - Chỉ cho phép các chú thích biến thể hiện trong các phương pháp: Vấn đề là nhiều phương thức
path = None # type: Optional[str] # Path to module source
9 thực hiện rất nhiều điều bên cạnh việc khởi tạo các biến thể hiện và sẽ khó hơn [đối với con người] để tìm tất cả các chú thích biến biến thể. Và đôi khipath = None # type: Optional[str] # Path to module source
9 được đưa vào các phương pháp trợ giúp hơn, vì vậy nó thậm chí còn khó khăn hơn để đuổi theo chúng. Đặt các chú thích biến thể hiện cùng nhau trong lớp giúp tìm thấy chúng dễ dàng hơn và giúp người đọc mã lần đầu tiên. The problem is that manypath = None # type: Optional[str] # Path to module source
9 methods do a lot of things besides initializing instance variables, and it would be harder [for a human] to find all the instance variable annotations. And sometimespath = None # type: Optional[str] # Path to module source
9 is factored into more helper methods so it’s even harder to chase them down. Putting the instance variable annotations together in the class makes it easier to find them, and helps a first-time reader of the code. - Sử dụng cú pháp
primes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}
07 cho các biến lớp: Điều này sẽ yêu cầu trình phân tích cú pháp phức tạp hơn và từ khóaprimes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}
08 sẽ gây nhầm lẫn cho các máy đánh bóng cú pháp có đầu óc đơn giản. Dù sao, chúng ta cần phải có các biến lớp lưu trữmy_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.
1 thànhsome_number: int # variable without initial value some_list: List[int] = [] # variable with initial value
5, vì vậy một cú pháp đơn giản hơn đã được chọn.primes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}
07 for class variables: This would require a more complicated parser and theprimes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}
08 keyword would confuse simple-minded syntax highlighters. Anyway we need to havemy_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.
1 store class variables tosome_number: int # variable without initial value some_list: List[int] = [] # variable with initial value
5, so a simpler syntax was chosen. - Quên về
my_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.
1 Hoàn toàn: Điều này đã được đề xuất vì MyPy dường như rất hợp nhau mà không có cách nào để phân biệt giữa các biến lớp và phiên bản. Nhưng trình kiểm tra loại có thể làm những điều hữu ích với thông tin bổ sung, ví dụ như các bài tập tình cờ cho một biến lớp thông qua phiên bản [sẽ tạo một biến thể hiện làm mờ biến lớp]. Nó cũng có thể gắn cờ các biến thể hiện với mặc định có thể thay đổi, một mối nguy hiểm nổi tiếng.my_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.
1 altogether: This was proposed since mypy seems to be getting along fine without a way to distinguish between class and instance variables. But a type checker can do useful things with the extra information, for example flag accidental assignments to a class variable via the instance [which would create an instance variable shadowing the class variable]. It could also flag instance variables with mutable defaults, a well-known hazard. - Sử dụng
primes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}
12 thay vìmy_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.
1: Lý do chính tại saomy_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.
1 tốt hơn là theo sau: nhiều thứ là thuộc tính lớp, ví dụ: Phương pháp, mô tả, v.v. nhưng chỉ các thuộc tính cụ thể là các biến lớp về mặt khái niệm [hoặc có thể là hằng số].primes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}
12 instead ofmy_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.
1: The main reason whymy_var: int my_var = 5 # Passes type check. other_var: int = 'a' # Flagged as error by type checker, # but OK at runtime.
1 is better is following: many things are class attributes, e.g. methods, descriptors, etc. But only specific attributes are conceptually class variables [or maybe constants]. - Không đánh giá các chú thích, coi chúng là chuỗi: điều này sẽ không phù hợp với hành vi của các chú thích chức năng luôn được đánh giá. Mặc dù điều này có thể được xem xét lại trong tương lai, nhưng nó đã được quyết định trong PEP 484 rằng đây sẽ phải là một PEP riêng biệt. This would be inconsistent with the behavior of function annotations that are always evaluated. Although this might be reconsidered in future, it was decided in PEP 484 that this would have to be a separate PEP.
- Chú thích các loại biến trong lớp DocString của lớp: Nhiều dự án đã sử dụng các quy ước khác nhau, thường không có nhiều tính nhất quán và nói chung mà không phù hợp với cú pháp chú thích PEP 484. Ngoài ra, điều này sẽ đòi hỏi một trình phân tích cú pháp tinh vi đặc biệt. Điều này, đến lượt nó, sẽ đánh bại mục đích của PEP - hợp tác với các công cụ kiểm tra loại bên thứ ba. Many projects already use various docstring conventions, often without much consistency and generally without conforming to the PEP 484 annotation syntax yet. Also this would require a special sophisticated parser. This, in turn, would defeat the purpose of the PEP – collaborating with the third party type checking tools.
- Thực hiện
some_number: int # variable without initial value some_list: List[int] = [] # variable with initial value
5 như một mô tả: Điều này đã được đề xuất để cấm thiết lậpsome_number: int # variable without initial value some_list: List[int] = [] # variable with initial value
5 cho một cái gì đó không phải là từ điển hoặc không không. Guido đã từ chối ý tưởng này là không cần thiết; Thay vào đó, một kiểu mẫu sẽ được nâng lên nếu một nỗ lực được thực hiện để cập nhậtsome_number: int # variable without initial value some_list: List[int] = [] # variable with initial value
5 khi nó là bất cứ thứ gì khác ngoài ánh xạ.some_number: int # variable without initial value some_list: List[int] = [] # variable with initial value
5 as a descriptor: This was proposed to prohibit settingsome_number: int # variable without initial value some_list: List[int] = [] # variable with initial value
5 to something non-dictionary or non-None. Guido has rejected this idea as unnecessary; instead a TypeError will be raised if an attempt is made to updatesome_number: int # variable without initial value some_list: List[int] = [] # variable with initial value
5 when it is anything other than a mapping. - Đối xử với các chú thích trần giống như toàn cầu hoặc không thuộc về: Đề xuất bị từ chối sẽ thích sự hiện diện của một chú thích mà không chuyển nhượng trong một cơ thể chức năng không nên liên quan đến bất kỳ đánh giá nào. Ngược lại, PEP ngụ ý rằng nếu mục tiêu phức tạp hơn một tên, thì phần tay trái của nó nên được đánh giá tại điểm xảy ra trong cơ thể chức năng, chỉ để thực thi nó được xác định. Ví dụ, trong ví dụ này: The rejected proposal would prefer that the presence of an annotation without assignment in a function body should not involve any evaluation. In contrast, the PEP implies that if the target is more complex than a single name, its “left-hand part” should be evaluated at the point where it occurs in the function body, just to enforce that it is defined. For example, in this example:
path = None # type: Optional[str] # Path to module source
3Tên
primes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}
18 nên được đánh giá, chỉ để nếu nó không được xác định [như có khả năng trong ví dụ này :-], lỗi sẽ bị bắt khi chạy. Điều này phù hợp hơn với những gì xảy ra khi có giá trị ban đầu, và do đó dự kiến sẽ dẫn đến ít bất ngờ hơn. [Cũng lưu ý rằng nếu mục tiêu làprimes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}
19 [lần này được đánh vần chính xác :-], một trình biên dịch tối ưu hóa không có nghĩa vụ đánh giáprimes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: ClassVar[Dict[str, int]] = {}
20 miễn là nó có thể chứng minh rằng nó chắc chắn sẽ được xác định.]
Khả năng tương thích ngược
PEP này hoàn toàn tương thích ngược.
Thực hiện
Một triển khai cho Python 3.6 được tìm thấy trên github repo tại //github.com/ilevkivskyi/cpython/tree/pep-526
Bản quyền
Tài liệu này đã được đặt trong phạm vi công cộng.