Hướng dẫn python local variable type hint - gợi ý kiểu biến cục bộ python

Tác giả: Ryan Gonzalez, Philip House, Ivan Levkivskyi, Lisa Roach, Guido Van Rossum Status: FinalType: Tiêu chuẩn theo dõi 2016Resolution: Thông điệp Python-Dev:Ryan Gonzalez , Philip House , Ivan Levkivskyi , Lisa Roach , Guido van Rossum Status:FinalType:Standards TrackTopic:Typing Created:09-Aug-2016Python-Version:3.6Post-History:30-Aug-2016, 02-Sep-2016Resolution:Python-Dev message
Mục lục
  • 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 source
8 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 source
9 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 = value
0. 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 source
9 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 = value
2 hoặc
var = value # type: annotation
var: annotation; var = value
var: annotation = value
3 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 = value
2 và
var = value # type: annotation
var: annotation; var = value
var: annotation = value
3 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 = value
6 hoặc
var = value # type: annotation
var: annotation; var = value
var: annotation = value
7; 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ô -đun
    var = 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ụ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 và xem phần bị từ chối để biết thêm thông tin về lý do đằng sau
    my_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ô -đun
    var = 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 value
5 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 value
5 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 value
5 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 source
7; 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 value
5 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 value
5 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 source
0

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 = False
3 hoặc
sane_world: bool
if 2+2 == 4:
    sane_world = True
else:
    sane_world = False
4.

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 value
5 sẽ bao gồm
sane_world: bool
if 2+2 == 4:
    sane_world = True
else:
    sane_world = False
6.

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ập
    sane_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 be
    sane_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 be
    sane_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 a
    sane_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
    
    1

    Vấ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ại
    my_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 đợi
    my_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ại
    a: 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ì trong
    var = 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à trong
    var = 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 and
    var = value # type: annotation
    var: annotation; var = value
    var: annotation = value
    
    6 statement: This was rejected because in
    var = value # type: annotation
    var: annotation; var = value
    var: annotation = value
    
    6 it would make it hard to spot the actual iterable, and in
    var = 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 trong
    primes: List[int] = []
    
    captain: str  # Note: no initial value!
    
    class Starship:
        stats: ClassVar[Dict[str, int]] = {}
    
    01 đến
    path = 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ựa
    primes: 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 in
    primes: List[int] = []
    
    captain: str  # Note: no initial value!
    
    class Starship:
        stats: ClassVar[Dict[str, int]] = {}
    
    01 to
    path = None  # type: Optional[str]  # Path to module source
    
    4 or to an additional special constant like Javascript’s
    primes: 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 khi
    path = 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 many
    path = 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 sometimes
    path = 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óa
    primes: 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ành
    some_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 the
    primes: 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 have
    my_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 to
    some_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 sao
    my_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 of
    my_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 why
    my_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ập
    some_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ật
    some_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 setting
    some_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 update
    some_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
    
    3

    Tê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 https://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.

Loại gợi ý trong Python là gì?

Loại gợi ý là một giải pháp chính thức để chỉ ra định nghĩa loại giá trị trong mã Python của bạn. Nó được chỉ định trong PEP 484 và được giới thiệu trong Python 3.5. Dưới đây là một ví dụ về việc thêm thông tin loại vào một chức năng.a formal solution to statically indicate the type of a value within your Python code. It was specified in PEP 484 and introduced in Python 3.5. Here's an example of adding type information to a function.

Bạn có thể chỉ định loại trong Python không?

Các phiên bản gần đây của Python cho phép bạn chỉ định các gợi ý loại rõ ràng có thể được sử dụng bởi các công cụ khác nhau để giúp bạn phát triển mã của mình hiệu quả hơn. Trong hướng dẫn này, bạn sẽ tìm hiểu về những điều sau: Loại chú thích và gợi ý loại. Thêm các loại tĩnh vào mã, cả mã của bạn và mã của người khác.

__ chú thích __ trong Python là gì?

Trong bài học này, bạn sẽ tìm hiểu về các chú thích trong Python. Các chú thích đã được giới thiệu trong Python 3.0 ban đầu mà không có bất kỳ mục đích cụ thể nào. Chúng chỉ đơn giản là một cách để liên kết các biểu thức tùy ý với các đối số chức năng và trả về các giá trị.a way to associate arbitrary expressions to function arguments and return values.

Python có thực thi gợi ý loại không?

Gợi ý loại được thực hiện bằng cách sử dụng các chú thích Python (được giới thiệu từ PEP 3107).Chúng được sử dụng để thêm các loại vào các biến, tham số, đối số hàm cũng như các giá trị trả về, thuộc tính lớp và phương thức của chúng.Thêm gợi ý loại không có hiệu ứng thời gian chạy: Đây chỉ là những gợi ý và không được thực thi.

PEP484 là gì?

PEP 484, cung cấp một đặc điểm kỹ thuật về hệ thống loại sẽ trông như thế nào trong Python3, đã đưa ra khái niệm về gợi ý loại.provides a specification about what a type system should look like in Python3, introduced the concept of type hints.