Python 3.7 có hỗ trợ gõ không?

Điều thú vị nhất đang xảy ra ngay bây giờ trong quá trình phát triển Python là gõ tĩnh. Kể từ Python 3. 0, chúng tôi đã có các chú thích chức năng và kể từ 3. 6, biến chú thích. Trong 3. 5, chúng tôi có một thư viện “đánh máy”, cung cấp các công cụ để mô tả các loại. Bạn đã thấy tôi sử dụng gợi ý loại

def f[x: int] -> int:
    return x * 5

Bạn có thể đã tự hỏi mình, điều đó làm gì?

f[["hi"]]

['hi', 'hi', 'hi', 'hi', 'hi']

Không. Nó không làm gì trong thời gian chạy, ngoại trừ lưu trữ đối tượng. Và trong Python 3 sắp tới. 11 hoặc 3. 12 [hoặc 3. 7+ với

def f[x: int] -> int:
    return x * 5
7], nó thậm chí không lưu trữ đối tượng thực tế, chỉ lưu trữ chuỗi bạn nhập ở đây, vì vậy, mọi thứ có thể vượt qua trình phân tích cú pháp Python đều được phép ở đây

Nó không phải là vô ích mặc dù. Đối với một, nó giúp người đọc. Việc biết các loại được mong đợi thực sự giúp bạn hiểu rõ hơn về những gì đang diễn ra và những gì bạn có thể làm và không thể làm

Nhưng mục tiêu chính là. kiểm tra kiểu tĩnh. Có một bộ sưu tập các trình kiểm tra kiểu tĩnh, trong đó "chính thức" và nổi tiếng nhất là MyPy. Bạn có thể coi đây là “trình biên dịch” cho các ngôn ngữ được biên dịch như C++; . Ví dụ

%%save_and_run mypy
def f[x: int] -> int:
    return x * 5

f[["hi"]]

tmp.py:4: error: Argument 1 to "f" has incompatible type "List[str]"; expected "int"
Found 1 error in 1 file [checked 1 source file]

chúng ta đi thôi. Và quan trọng nhất, chúng tôi không phải chạy bất kỳ mã nào để thấy lỗi này. Các bài kiểm tra của bạn không thể kiểm tra mọi nhánh có thể, mọi dòng mã. MyPy có thể [mặc dù theo mặc định thì không, do gõ dần dần]. Bạn có thể có mã hiếm khi chạy, yêu cầu tài nguyên từ xa, chậm, v.v. Tất cả những thứ đó có thể được kiểm tra bởi MyPy. Nó cũng giữ cho bạn [cũng vậy?] trung thực trong các loại của bạn

10. 1. 1. Đang bắt lỗi#

Hãy xem một ví dụ về lỗi mà MyPy có thể bắt gặp

%%save_and_run mypy
from __future__ import annotations  # Python 3.7+


def f[x: int | None] -> int | None:
    return x * 5

f[4]

tmp.py:5: error: Unsupported operand types for * ["None" and "int"]
tmp.py:5: note: Left operand is of type "Optional[int]"
Found 1 error in 1 file [checked 1 source file]

Bộ thử nghiệm của bạn có thể đã quên chạy với đầu vào

def f[x: int] -> int:
    return x * 5
8. Bạn không được gặp
def f[x: int] -> int:
    return x * 5
8 thường xuyên, cho đến khi bạn rơi vào tình huống nguy cấp. Nhưng MyPy có thể tìm thấy nó và cho bạn biết có vấn đề về logic, chức năng của bạn không thể mất
def f[x: int] -> int:
    return x * 5
8 như tuyên bố của nó

10. 1. 2. Thêm loại#

Có ba cách để thêm các loại

  1. Chúng có thể là nội tuyến dưới dạng chú thích. Tốt nhất cho mã Python 3, thường là

  2. Họ có thể ở trong "loại bình luận" đặc biệt. Hầu hết được yêu cầu đối với mã Python 2 và vẫn yêu cầu nhập đúng cách [một lý do tại sao phần đóng gói lại quan trọng như vậy, tùy thuộc vào các thư viện như backport có quan trọng không]

  3. Chúng có thể nằm trong một tệp riêng có cùng tên nhưng có phần mở rộng

    f[["hi"]]
    
    1. Điều này rất quan trọng đối với sơ khai loại hoặc đối với trường hợp bạn không muốn thêm nhập hoặc chạm vào mã gốc. Bạn có thể chú thích các tệp hoặc thư viện đã biên dịch mà bạn không kiểm soát theo cách này

Nếu bạn có một thư viện mà bạn không kiểm soát, bạn có thể thêm “type stubs” cho nó, sau đó cung cấp cho MyPy thư mục stubs của bạn. MyPy sẽ lấy các loại từ sơ khai của bạn. Ví dụ: nếu bạn đang viết mã cho Raspberry Pi, bạn có thể thêm sơ khai cho các thư viện Pi, sau đó xác thực mã của mình mà không cần cài đặt các thư viện chỉ dành cho Pi

10. 1. 3. Cấu hình#

Theo mặc định, MyPy thực hiện càng ít càng tốt để bạn có thể thêm nó lặp đi lặp lại vào cơ sở mã. Theo mặc định

  • Tất cả các biến chưa được nhập và giá trị trả về sẽ là Bất kỳ

  • Mã bên trong các chức năng chưa nhập hoàn toàn không được kiểm tra

Bạn có thể thêm cấu hình vào

f[["hi"]]
2 [và một chút vào chính các tệp] hoặc bạn có thể thực hiện mọi cách và vượt qua
f[["hi"]]
3, thao tác này sẽ bật mọi thứ

Để một thư viện hỗ trợ nhập liệu, nó phải a] thêm các loại bằng cách sử dụng bất kỳ phương pháp nào trong ba phương pháp và b] thêm một tệp trống

f[["hi"]]
4 để cho biết rằng bạn có thể tìm kiếm các loại bên trong nó. MyPy cũng xem trong
f[["hi"]]
5, đây là thư viện có đầy đủ các gợi ý về loại cho [hầu hết] thư viện chuẩn

Nhân tiện, các thư viện của bên thứ ba được nhập đôi khi quên bước cuối cùng này

Cá nhân tôi khuyên bạn nên sử dụng pre-commit để chạy tất cả các kiểm tra của bạn ngoại trừ pytest [và điều đó chỉ vì nó có thể chậm] và bao gồm cả MyPy trong thử nghiệm pre-commit của bạn. Cố gắng bật càng nhiều càng tốt và tăng dần cho đến khi bạn có thể chạy với đầy đủ

f[["hi"]]
6 kiểm tra

10. 1. 4. Các tính năng khác#

Gõ tĩnh có một số tính năng tuyệt vời đáng để kiểm tra

  • Công đoàn [Cú pháp mới trong Python 3. 10]

  • Các loại chung [Cú pháp mới trong Python 3. 9]

  • giao thức

  • chữ

  • đã gõDict

  • Định nghĩa NamedTuple đẹp hơn [rất phổ biến trong mã Python 3]

  • MyPy xác thực phiên bản Python mà bạn yêu cầu

10. 2. Ví dụ mở rộng#

Đây là cú pháp cổ điển mà bạn cần sử dụng nếu hỗ trợ 3. 6+

f[["hi"]]
7

f[["hi"]]
8

Với

def f[x: int] -> int:
    return x * 5
7 trong Python 3. 7, các chú thích không còn được đánh giá trong thời gian chạy và do đó, điều này hợp lệ trên Python 3. 7 và MyPy

def f[x: int] -> int:
    return x * 5
0

f[["hi"]]
8

Lưu ý rằng tôi thậm chí không phải nhập bất cứ thứ gì từ việc gõ. Lưu ý rằng bạn không thể sử dụng cú pháp “mới” ở những vị trí không có chú thích [như liên kết trong

f[["hi"]]
8] cho đến khi Python hỗ trợ nó

Bạn có thể sử dụng phần trên trong các phiên bản Python cũ hơn nếu bạn sử dụng chuỗi

Khi chạy cùng với một kẻ nói dối giỏi như flake8, điều này có thể phát hiện ra rất nhiều vấn đề trước khi kiểm tra hoặc chúng được phát hiện ngoài tự nhiên. Nó cũng nhắc thiết kế tốt hơn, bởi vì bạn đang suy nghĩ về cách các loại hoạt động và tương tác. Nó cũng dễ đọc hơn, vì nếu tôi cung cấp cho bạn mã như thế này

def f[x: int] -> int:
    return x * 5
2

Bạn không biết dấu thời gian "là gì". Nó là một int? . Bạn có thể sử dụng bí danh loại để thực sự đặt tên biểu cảm ở đây

10. 3. Giao thức#

Một trong những tính năng tốt nhất của MyPy là hỗ trợ phân nhóm cấu trúc thông qua Giao thức - về cơ bản là kiểu gõ vịt được chính thức hóa. Điều này cho phép khả năng tương tác giữa các thư viện, không giống như kế thừa truyền thống. Đây là cách nó hoạt động

def f[x: int] -> int:
    return x * 5
3

Vâng,

f[["hi"]]
9 thực sự là một phần của mã ở đây;

Giờ đây, bất kỳ đối tượng nào có thể “quack” [và trả về một chuỗi] đều là Vịt. Chúng tôi thậm chí có thể thêm

['hi', 'hi', 'hi', 'hi', 'hi']
1, điều này sẽ cho phép chúng tôi kiểm tra điều này [trừ các loại] khi chạy trong
f[["hi"]]
8. Vì vậy, bây giờ chúng ta có thể thiết kế mã như thế này

def f[x: int] -> int:
    return x * 5
4

Và trình kiểm tra loại sẽ đảm bảo chúng tôi chỉ viết mã hợp lệ trên tất cả các “Vịt”. Và, chúng ta có thể viết triển khai duck và kiểm tra nó như thế này

def f[x: int] -> int:
    return x * 5
5

Điều này sẽ vượt qua kiểm tra để trở thành Vịt, ví dụ như thế này

def f[x: int] -> int:
    return x * 5
6

Lưu ý hoàn toàn thiếu phụ thuộc ở đây. Chúng tôi không cần

['hi', 'hi', 'hi', 'hi', 'hi']
3 để viết
['hi', 'hi', 'hi', 'hi', 'hi']
4 hoặc ngược lại. Và, chúng tôi thậm chí không cần
['hi', 'hi', 'hi', 'hi', 'hi']
5 để viết một trong hai trong thời gian chạy. Sự phụ thuộc vào Vịt cho
['hi', 'hi', 'hi', 'hi', 'hi']
4 hoàn toàn là sự phụ thuộc kiểu-kiểm tra-thời gian [trừ khi chúng tôi muốn sử dụng một
f[["hi"]]
8 được cung cấp bởi
['hi', 'hi', 'hi', 'hi', 'hi']
7]

Có rất nhiều Giao thức tích hợp, hầu hết trong số đó được nhập trước ngày và có sẵn ở dạng Lớp cơ sở trừu tượng. Hầu hết trong số họ kiểm tra một hoặc nhiều phương thức đặc biệt, như Iterable, Iterator, v.v.

Liệu Python 3. 8 hỗ trợ gõ?

Tuy nhiên, trong Python 3. 8, một số tính năng mới đã được thêm vào tính năng nhập để cho phép nhập chính xác hơn . các loại chữ. từ điển đánh máy. đối tượng cuối cùng.

Tính năng gõ có được bao gồm trong Python không?

Kiểu gõ xác định ký hiệu chuẩn cho hàm Python và chú thích loại biến . Ký hiệu có thể được sử dụng để ghi lại mã ở định dạng tiêu chuẩn, ngắn gọn và được thiết kế để cũng được sử dụng bởi trình kiểm tra kiểu tĩnh và thời gian chạy, trình phân tích tĩnh, IDE và các công cụ khác.

Kiểu gõ nào được Python hỗ trợ?

Thời gian chạy Python không thực thi chức năng và chú thích loại biến. Chúng có thể được sử dụng bởi các công cụ của bên thứ ba như trình kiểm tra loại, IDE, linters, v.v. Mô-đun này cung cấp hỗ trợ thời gian chạy cho các gợi ý loại. Hỗ trợ cơ bản nhất bao gồm các loại Any , Union , Callable , TypeVar và Generic .

Liệu Python 3. 6 gợi ý loại hỗ trợ?

Bạn có thể thêm gợi ý loại cho tham số hàm/phương thức và loại trả về [Python 3. 5] và các biến được sử dụng trong phép gán [khai báo hiệu quả – Python 3. 6].

Chủ Đề