Python có kiểm tra kiểu không?

Khám phá điều gì làm cho việc kiểm tra kiểu trong Python trở nên tuyệt vời như vậy, tại sao lợi ích của nó không chỉ giới hạn ở mức độ an toàn và cách chúng tôi sử dụng các công cụ này trong thu nhập cố định có hệ thống

Qua. Cristian Matache, Kỹ sư lượng tử hệ thống, Nhóm quản lý danh mục đầu tư

Vịt đã đi đâu?

Tất cả chúng ta đều yêu thích Python vì nhiều phẩm chất của nó. nó cực kỳ linh hoạt, linh hoạt, thú vị để viết và có một hệ sinh thái gói rộng lớn. Không có gì ngạc nhiên khi nó đã trở thành tiêu chuẩn thực tế trong một số lĩnh vực. Nhưng trong khi tính linh hoạt của nó làm cho Python trở nên lý tưởng để tạo nguyên mẫu, thì nó cũng khiến việc phát triển và bảo trì các thư viện và nền tảng lớn trở nên cồng kềnh hơn. Trong các ngôn ngữ khác, đánh máy được chứng minh là cứu cánh trong những trường hợp như vậy; . Trong bài đăng này, chúng tôi sẽ khám phá điều gì làm cho việc kiểm tra kiểu trở nên tuyệt vời như vậy, tại sao lợi ích của nó không chỉ giới hạn ở mức độ an toàn và cách chúng tôi sử dụng các công cụ này trên BlackRock. Nếu không tò mò về bất kỳ điều gì trong số này, hãy tiếp tục theo dõi để biết những chú vịt đã đi đâu 😉

Nó là gì?

Rắc mã của bạn bằng các chú thích loại và xác minh chương trình của bạn bằng trình kiểm tra loại, chẳng hạn như mypy phổ biến. Mặc dù Python vẫn là một ngôn ngữ được nhập động, nhưng việc thêm các gợi ý về loại và kiểm tra chúng một cách tĩnh sẽ kết hợp các điểm mạnh của ngôn ngữ được biên dịch với tính linh hoạt tự nhiên của Python. Trình kiểm tra loại được sử dụng như linters, với các chú thích loại bị bỏ qua khi chạy

Cú pháp khá đơn giản. Trong ví dụ này, my_sum lấy danh sách các số nguyên và boolean làm đầu vào và trả về một số nguyên

Python cung cấp một hệ thống kiểu mạnh mẽ và dễ sử dụng với các tính năng hiện đại như suy luận kiểu, kiểu kết hợp, kiểu tổng quát và cả kiểu con cấu trúc và danh nghĩa trong khi cho phép bạn quay lại kiểu gõ động nếu cần. Typing làm cho các chương trình Python dễ hiểu, gỡ lỗi và bảo trì hơn. Cú pháp được hỗ trợ từ Python 3. 5, trong khi đối với các phiên bản trước đó, người ta có thể thêm chú thích dưới dạng nhận xét nội tuyến hoặc tệp sơ khai riêng biệt [mỗi. tệp py được ghép nối với một. pyi chú thích tất cả các chữ ký trong. tập tin py]

Tại sao lại sử dụng nó?

Bởi vì nó làm cho cuộc sống dễ dàng hơn. Mục tiêu chính là làm cho các chương trình trở nên mạnh mẽ hơn bằng cách phát hiện sớm cả các lỗi phổ biến và khó phát hiện. Tuy nhiên, việc gõ cũng nâng cao trải nghiệm lập trình tổng thể thông qua tính năng tự động hoàn thành IDE và kiểm tra thời gian thực, mã tự viết tài liệu, tránh các bài kiểm tra soạn sẵn và các khái niệm có thể chuyển đổi từ các ngôn ngữ khác. Kiểm tra phần 'Ưu điểm' ở cuối để biết thêm

Vì nó trở nên bình thường. Kiểm tra kiểu tĩnh đã xuất hiện được vài năm và đang trở thành tiêu chuẩn. Những gã khổng lồ công nghệ như Dropbox, Facebook, Google và Quora đã dẫn đầu trong việc phát triển các công cụ và tận dụng các lợi ích. Ví dụ, loại Dropbox đã kiểm tra hơn 4 triệu dòng mã Python. Tất cả các công ty này cũng triển khai trình kiểm tra loại của riêng họ, mypy của Dropbox và pyre của Facebook là phổ biến nhất. Các dự án nguồn mở quan trọng cũng đang dẫn đầu, bao gồm Airflow [dự án Apache Python lớn nhất], FastAPI, Prefect và các thư viện async-io

Vì nó hợp thời trang. Kể từ năm 2015, kiểm tra kiểu đã là một chủ đề rất nóng tại các hội nghị Python. nó đã xuất hiện trong 10 bài giảng về PyCon, 6 Europython và hàng chục PyCon địa phương. Xu hướng không giới hạn ở Python. Ban đầu, Flow làm phong phú JavaScript với các loại; . PHP cũng đã thêm các gợi ý về loại, trong khi hầu hết Facebook được cung cấp bởi Hack, một phương ngữ PHP được nhập khác. Ruby cũng có tính năng gõ dần dần thông qua Sorbet. Đánh máy được hầu hết "những đứa trẻ tuyệt vời" mới thực hiện nghiêm túc. Scala, Kotlin, Dart, Rust và bởi những người hipster-ish nhất, bao gồm Nim, Pony và Clojure

Bởi vì Guido đã nói như vậy. Dự án mypy được bắt đầu bởi Jukka Lehtosalo, người sau đó được tham gia bởi chính Guido van Rossum, “nhà phát minh” của Python và cựu BDFL

Khi nào thì sử dụng nó?

Trong bài báo xuất sắc của mình “Trạng thái của gợi ý kiểu trong Python”, Bernat Gabor khuyến nghị rằng “Nên sử dụng gợi ý kiểu bất cứ khi nào các bài kiểm tra đơn vị đáng để viết”, realpython. com củng cố tuyên bố của mình

  • Điều này rất dễ thực hiện đối với các dự án mới. ”Được chú thích 100% từ ngày đầu tiên → nhập kiểm tra CI → lợi nhuận” như được khuyên trong rất nhiều PyCon
  • Khi xử lý các cơ sở mã lớn hiện có, lợi thế là Python cho phép nhập dần dần. Chúng tôi khuyên bạn nên nhập và kiểm tra xương sống của cơ sở mã để đảm bảo rằng dự án được xây dựng trên nền tảng vững chắc, sau đó đóng góp mã đã nhập trong tương lai. Khi viết một thư viện, thật tuyệt khi chú thích các chức năng hướng tới người dùng để IDE tự động hoàn thành và kiểm tra kiểu ở cuối của chúng. Các công cụ như Pyannotate hoặc MonkeyType thậm chí có thể được sử dụng để tự động chú thích mã. Có một trình kiểm tra kiểu như mypy trong CI rất hữu ích ngay cả khi không có chú thích vì nó kiểm tra sự tồn tại của tất cả các lớp và hàm được tham chiếu trong quá trình nhập
Làm thế nào để sử dụng nó?

Cuộc sống trước khi loại chú thích

Hãy nghĩ về một nhiệm vụ rất phổ biến. gửi công việc. Mỗi công việc có một id và có thể được gửi. Trong Python kiểu cũ, người ta sẽ viết mã như bên dưới. Để trở thành những công dân tốt, trong cuộc sống thực, chúng ta cũng phải thực hiện các phương pháp như __eq____repr__

Bây giờ hãy xem cách chúng ta viết một hàm để gửi một số công việc

Như bạn có thể thấy, thật khó để nói loại công việc nào và loại công việc submit_jobs có thể lặp lại nào. Trong trường hợp này, rõ ràng là các công việc không thể là một trình tạo vì nó không có kích thước, nhưng trong các tình huống thực tế, rất khó để làm việc ngược lại. Đoạn mã trên cho thấy một số hành vi nguy hiểm tiềm tàng. nộp công việc một phần

Cuộc sống sau khi chú thích loại

Trong Python “hiện đại”, chúng ta có thể sử dụng cách gõ để làm cho ví dụ của chúng ta dễ đọc hơn nhiều. Trong phần sau đây, chúng tôi sử dụng Literal để nói rằng một số thuộc tính chỉ nhận các giá trị trong một tập hợp hữu hạn. Chúng tôi cũng đang sử dụng các lớp dữ liệu giúp giảm nhu cầu về mã soạn sẵn như __init__, __eq__, __repr__, nhưng bắt buộc phải nhập

Một điều quan trọng cần lưu ý là ví dụ này sẽ kích hoạt lỗi trình kiểm tra loại nhưng sẽ không gây ra ngoại lệ thời gian chạy nếu một trạng thái vượt qua st4. Sự sang trọng của cú pháp dataclass/Literal đi kèm với chi phí phụ thuộc vào các công cụ kiểm tra loại của chúng tôi. Tuy nhiên, nếu một người muốn xác thực các đối số trong thời gian chạy, thì người đó có thể thêm một trình trang trí khác vào lớp dữ liệu. __eq__0 Pydantic là thư viện cho phép kiểm tra kiểu thời gian chạy dựa trên chú thích kiểu. Trình trang trí pydantic tương tự cũng có thể được áp dụng cho các hàm/phương thức

Cuộc sống với chú thích loại

Bây giờ, quay lại gửi công việc. Chúng ta có thể biết một cách an toàn loại công việc nào và loại lặp lại nào được mong đợi. Trong các nhận xét sau, chúng tôi sẽ sử dụng “TỐT” có nghĩa là “kiểm tra loại thành công” và “BAD” có nghĩa là “lỗi loại tĩnh”

Ngoài mypy và pyre [công cụ kiểm tra chính], PyCharm cung cấp trình kiểm tra loại tích hợp cung cấp phản hồi khi bạn nhập — không cần chạy bất kỳ thứ gì. Tuy nhiên, chức năng của nó bị hạn chế. Ví dụ: trong ví dụ trên, các loại hỗn hợp không bị gắn cờ là sai mặc dù rõ ràng chúng đang vi phạm các khai báo loại của chúng tôi. Tuy nhiên, đây là một tính năng khá hữu ích và có khả năng gắn cờ một số vấn đề, đồng thời nó vẫn tiếp tục được cải thiện. Chúng tôi sử dụng TỐT/XẤU cho những gì mypy đồng ý/không đồng ý, vì cho đến nay, đây là công cụ chuyên dụng hơn

Các loại liên minh

Giả sử rằng chúng ta muốn sử dụng cùng một hàm submit_jobs cho cả hai loại công việc. Đây là lúc các loại Union có ích. __eq__2 có nghĩa là nó có thể là __eq__3hoặc là __eq__4. Mã mà bạn viết phải phục vụ cho cả hai loại hoặc xử lý rõ ràng các trường hợp đặc biệt

Quan sát rằng danh sách loại hỗn hợp được cho phép. Ví dụ: nếu chúng tôi muốn không cho phép danh sách loại hỗn hợp, chúng tôi chuyển sang loại biến. Gõ gợi ý trong Python rất linh hoạt và, như chúng tôi sẽ chỉ ra, mạnh mẽ

Loại biến

Các biến loại có nghĩa là chúng có thể được thay thế bằng bất kỳ loại "cụ thể" nào, có khả năng áp dụng một số điều kiện. Ví dụ: bên dưới __eq__5 có thể là __eq__6 hoặc __eq__7, trình kiểm tra loại sẽ suy ra cái nào

Để minh họa cách các biến kiểu bị ràng buộc, hãy lấy một ví dụ khác. trả về một phần tử ngẫu nhiên từ một chuỗi/danh sách. Điều đáng nói ở đây là chúng ta không thể có một loại var đầu ra không xuất hiện ở đâu đó trong đầu vào. Chúng ta sẽ xem sau cách sử dụng Generics để khắc phục điều này

“reveal_type” là một hàm mypy không tồn tại trong Python. Nghĩa là, nó sẽ in ra các loại khi chạy mypy để hiểu sâu hơn về những gì mypy nhìn thấy nhưng cần phải xóa trước khi chạy mã Python

Những con vịt đã đi đâu? . k. a. giao thức

Gõ vịt rất tốt cho việc tạo mẫu nhưng khá dễ vỡ trong các hệ thống lớn. Tuy nhiên, Pythonistas thích sự đơn giản của cách gõ vịt. May mắn thay, phân loại cấu trúc đến để giải cứu. Nó tương tự như các giao diện Java với ngoại lệ là các lớp không "triển khai" giao diện một cách rõ ràng. Quay trở lại ví dụ công việc của chúng tôi. nếu trong tương lai, chúng tôi có thể thêm __eq__8, __eq__9, v.v. thì sao? . Điều này rõ ràng là khó bảo trì, gây phiền nhiễu và không phải Pythonic. Điều chúng tôi muốn nói là. miễn là nó có một trường/thuộc tính được gọi là “id” có thể băm được [e. g. __repr__1, __repr__2, v.v.] và một phương thức có tên là __repr__3, chúng ta có thể truyền nó cho hàm submit_jobs của mình. Chúng ta có thể sử dụng một Giao thức [a. k. một giao diện] để làm cho kiểu gõ vịt an toàn

Các giao thức không nhất thiết phải chung chung [i. e. phụ thuộc vào một biến loại như H]. Nếu bạn tò mò về cách __repr__5cho phép __repr__6kiểm tra mà không cần thừa kế, siêu dữ liệu sẽ phát huy tác dụng [ __repr__7, __repr__8, __repr__9]. Chỉ cần FYI, phân loại thông qua kế thừa được gọi là phân loại danh nghĩa trong khi phân loại thông qua cấu trúc được gọi là phân loại cấu trúc. Các “giao thức” Python có thể được coi là song song với các “khái niệm” C++, “giao diện” TypeScript, “các lớp kiểu” Scala/Haskell, v.v.

Thêm Generics, Quá tải, Tham chiếu chuyển tiếp

Tóm tắt lại

  • Các biến loại đầu ra phải được ràng buộc bởi các biến đầu vào của hàm
  • Khi sử dụng các loại Liên minh, chúng tôi có nghĩa là bất kỳ loại công đoàn nào cũng có thể như nhau

Trong ví dụ dưới đây, chúng tôi xây dựng một danh sách tùy chỉnh. Chúng tôi chỉ ra cách submit_jobs0 liên kết biến kiểu với cả lớp. Nghĩa là, tất cả các T trong lớp này phải giống nhau và do đó chúng ta có thể trả về T mà không cần có T làm đầu vào [vì T bị ràng buộc ở cấp lớp thay vì cấp chức năng như S]. Hơn nữa, chúng tôi sử dụng quá tải để xác định rằng submit_jobs1 hoặc trả về T nếu được cung cấp __repr__1 hoặc ____3_______3 nếu được cung cấp một lát cắt như submit_jobs4. Quá tải về cơ bản loại trừ submit_jobs5 và submit_jobs6 sẽ được xem xét nếu chỉ chú thích với Unions. Lần đầu tiên chúng tôi cũng sử dụng các tham chiếu chuyển tiếp [trong dấu ngoặc kép] và phác thảo mẫu cho các phương thức xuất xưởng như “trống rỗng”

Để tìm hiểu thêm, độc giả tò mò có thể tiếp tục và đọc về vars loại covariant và contravariant [hoặc functor nói chung]. Mặc dù nằm ngoài phạm vi, nhưng nếu bạn muốn tìm hiểu vị trí của các đơn nguyên và hàm ứng dụng phù hợp, hãy theo dõi các dự án như dry-python

ưu
  • mạnh mẽ. Kiểm tra kiểu là một phương tiện kiểm tra để nó làm cho mã mạnh mẽ hơn và loại bỏ nhu cầu kiểm tra bản mẫu, do đó cho phép các kỹ sư tập trung vào kiểm tra logic hơn là các ngoại lệ. Phạm vi kiểm tra cũng tự động trở thành một số liệu có ý nghĩa hơn vì các bài kiểm tra đang diễn ra
  • Trải nghiệm người dùng phong phú. IDE sử dụng chú thích cho mục đích tự động hoàn thành và tái cấu trúc. Typed Python được tự ghi lại để dễ đọc và ngắn gọn hơn. Các tài liệu trở nên nhỏ hơn khi tập trung vào logic và không còn có thể trở nên cũ kỹ
  • Tiết lộ mùi mã sớm. Các loại rất phức tạp như “List[Tuple[Job, Dict[str, int], Dict[Tuple[bool, bool], int]]]” chỉ ra rằng mã không hoàn toàn đúng → tái cấu trúc sớm hơn là muộn
  • Không già đi. Loại an toàn đến từ các mô hình lý thuyết hợp lý đã được nghiên cứu và sử dụng trong nhiều năm
  • các từ thông dụng. Có thể mở rộng — hệ sinh thái trưởng thành của các tệp sơ khai và plugin, Có thể chuyển đổi — cú pháp nhập rất giống với rất nhiều ngôn ngữ lập trình khác, Có thể mở rộng — daemon “dmypy” được thiết kế để hoạt động trên các cơ sở mã thực sự lớn, Dần dần — mã đã nhập và chưa nhập có thể cùng tồn tại. Có thể truy cập - mypy được cài đặt qua pip
  • Làm cho mã nhanh hơn. Với việc bổ sung mypyc, người ta có thể biên dịch các mô-đun Python được chú thích thành các phần mở rộng C, do đó cải thiện đáng kể hiệu suất
Nhược điểm

Mặt khác, người ta sẽ cần học một chút cú pháp Python mới và các gói số như Pandas có hỗ trợ hạn chế theo mặc định và các sáng kiến ​​như Pandara nhằm mục đích thu hẹp khoảng cách này. Numpy đang thúc đẩy làn sóng bằng cách tích cực thêm sơ khai loại. Nghiên cứu cho thấy rằng kiểm tra kiểu tĩnh cải thiện đáng kể chất lượng mã nhưng nó không hoàn toàn giúp chúng ta thoát khỏi mã xấu;

Chúng tôi cũng đã xác định được một số hạn chế của mô-đun nhập liệu, chẳng hạn như thiếu các biến kiểu biến đổi [so với các mẫu biến đổi trong C++] hoặc các loại có loại cao hơn [HKT], nhưng may mắn thay, các tính năng này được tích hợp trong thư viện lõi Python hoặc trong các dự án như . Trong thời gian tạm thời, trong nhóm của chúng tôi, chúng tôi đã viết sơ khai và plugin mypy để mở khóa tiềm năng kiểm tra loại đầy đủ trên thư viện của chúng tôi

Làm thế nào để nó làm việc cho chúng tôi?

Với tư cách là một nhóm, chúng tôi đã sớm ủng hộ kiểu gợi ý trong BlackRock và cảm thấy đã đến lúc chia sẻ trải nghiệm cực kỳ tích cực mà chúng tôi đã có. Tại thời điểm viết bài, chúng tôi đã có hàng chục nghìn dòng mã Python đã nhập. Những Ưu điểm ở trên chủ yếu được rút ra từ kinh nghiệm cá nhân của chúng tôi với kỹ thuật này và những gì chúng tôi học được từ nó

Kiểm tra loại đặc biệt hữu ích ở những nơi khó đạt được phạm vi kiểm tra đơn vị cao, chẳng hạn như quét web hoặc quy trình ETL dữ liệu thay thế. Hơn nữa, kiểm tra loại đã giúp chúng tôi thất bại sớm. một khi chúng tôi vận chuyển một thứ gì đó, việc xem lại nó là khá hiếm trừ khi một hệ thống mà chúng tôi phụ thuộc vào đã thay đổi. Thêm các tính năng mới cũng dễ dàng hơn. Kiểm tra loại có hiệu ứng quả cầu tuyết. càng nhiều chú thích, càng dễ dàng mở rộng hệ thống mà không phá vỡ nó. Vì nhóm của chúng tôi làm việc trên khá nhiều thư viện cùng một lúc, các nhà phát triển và người dùng có thể hưởng lợi từ việc tăng tốc độ tương ứng thông qua tính năng tự động hoàn thành và tự động lập tài liệu IDE. Điều này có nghĩa là các yêu cầu hỗ trợ được giảm đáng kể, giải phóng thời gian cho cả nhà phát triển và người dùng cuối

Phụ lục — Cú pháp đơn giản hóa

Trong Trăn 3. 10, cú pháp nhập đã được cải thiện, nhưng thông qua một lần nhập đơn giản submit_jobs7, chúng ta có thể hưởng lợi từ cùng một cú pháp bắt đầu từ Python 3. 7. Nghĩa là, thay vì nhập các lớp “bóng tối” cho các lớp dựng sẵn như submit_jobs8, submit_jobs9, Literal0, chúng ta có thể sử dụng chúng trực tiếp. Tương tự, các loại liên kết có thể được xác định bằng "cú pháp đường ống" giống như trong TypeScript. Ví dụ

Có trình kiểm tra loại cho Python không?

Mypy là trình kiểm tra kiểu tĩnh tùy chọn dành cho Python nhằm mục đích kết hợp các lợi ích của kiểu nhập động [hoặc "vịt"] và kiểu nhập tĩnh. Mypy kết hợp sức mạnh biểu cảm và sự tiện lợi của Python với hệ thống kiểu mạnh mẽ và kiểm tra kiểu thời gian biên dịch.

Kiểm tra kiểu hoạt động như thế nào trong Python?

Việc kiểm tra kiểu của loại biến được thực hiện trong thời gian chạy . Ngoài ra, hệ thống loại của ngôn ngữ không bắt buộc phải khai báo rõ ràng 'kiểu dữ liệu' của biến trước khi sử dụng. Các ngôn ngữ lập trình được gõ động là. Python, Javascript, Ruby, v.v.

Python có gợi ý kiểu không?

Với Python 3. 5, gợi ý nhập đã chính thức trở thành một phần của ngôn ngữ [PEP 484]. Sử dụng công cụ kiểm tra mã hoặc kẻ nói dối, nhà phát triển có thể kiểm tra tính nhất quán của các biến và loại của chúng trên cơ sở mã và thực hiện các phân tích mã tĩnh mà trước đây khó hoặc không thể thực hiện được.

Loại có được kiểm tra khi chạy trong Python không?

Các loại Python không cung cấp tính năng kiểm tra loại thời gian chạy .

Chủ Đề