Tìm hiểu cách sử dụng cú pháp gợi ý loại tùy chọn của Python để tạo cơ sở mã sạch hơn và hữu ích hơn.
Nhà văn cao cấp, Infoworld |InfoWorld |
Mục lục
Cho xem nhiều hơn
Python được coi là một ngôn ngữ năng động, nhưng gõ mạnh mẽ. Các loại aren liên kết với các tên cho mọi thứ, nhưng với chính những điều.
Điều này làm cho Python linh hoạt và thuận tiện cho các nhà phát triển, bởi vì bạn không phải xác định nghiêm ngặt và theo dõi các loại biến nếu bạn chỉ cần ném một kịch bản nhanh chóng. Nhưng đối với các dự án lớn hơn, đặc biệt là các thư viện được sử dụng bởi các bên thứ ba, nó giúp biết loại đối tượng nào được liên kết với các biến nào.
Hiện tại, Python đã có khả năng chú thích tên của người dùng với thông tin loại, dưới dạng này hay dạng khác. Với Python 3.5, các gợi ý loại chính thức trở thành một phần của ngôn ngữ [PEP 484]. Sử dụng một công cụ kiểm tra linter hoặc kiểm tra mã, các 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 tĩnh của mã trước đây là khó khăn hoặc không thể. Tất cả điều này được thực hiện trước thời hạn, trước khi mã chạy.
Trong bài viết này, chúng tôi sẽ khám phá một số ví dụ cơ bản về gợi ý loại Python. Nhưng trước tiên, chúng tôi sẽ làm rõ một sự hiểu lầm phổ biến về những gì nó là và được sử dụng cho.
Làm thế nào Python sử dụng gợi ý loại [nó không có]
Một quan niệm sai lầm quan trọng về gợi ý loại Python là cách chúng được sử dụng. Gợi ý loại Python không được sử dụng trong thời gian chạy. Trên thực tế, vào thời điểm chương trình của bạn chạy, tất cả các loại thông tin mà bạn đã cung cấp đã bị xóa. Gợi ý loại Python chỉ được sử dụng trước thời hạn, bởi hệ thống kiểm tra loại mà bạn sử dụng, ví dụ như trong trình soạn thảo hoặc IDE của bạn. Nói cách khác, gợi ý loại Python sườn dành cho nhà phát triển, không phải cho thời gian chạy.
Điều này nghe có vẻ phản trực giác, đặc biệt là nếu bạn đã có kinh nghiệm với các ngôn ngữ mà các khai báo loại không phải là tùy chọn. Nhưng đội ngũ phát triển của Python, đã cố gắng nói rõ rằng gợi ý loại đó là một khúc dạo đầu cho ngôn ngữ Python cốt lõi trở nên được đánh máy thống kê. Họ là một cách để các nhà phát triển thêm siêu dữ liệu vào cơ sở mã để giúp thực hiện phân tích tĩnh dễ dàng hơn trong quá trình phát triển.
Một số người đã suy đoán rằng gợi ý loại Python có thể phát sinh một ngã ba ngôn ngữ được đánh máy tĩnh, có lẽ là một cách để làm cho Python nhanh hơn. Trong một số cách, điều này đã đến. Cython sử dụng các gợi ý loại [mặc dù chủ yếu là giống riêng của chúng] để tạo mã C từ Python và dự án mypyc
sử dụng gợi ý loại bản địa Python tựa để làm điều tương tự.
Nhưng các dự án này được coi là bổ sung chính xác cho ngôn ngữ Python cốt lõi hơn là các dấu hiệu về nơi Python dự định sẽ đi. Mục đích chính của việc gợi ý loại trong Python là cung cấp cho các nhà phát triển một cách để làm cho mã của họ tự mô tả nhất có thể, cả vì lợi ích riêng của họ và của các nhà phát triển khác.
Cú pháp của các gợi ý loại Python
Loại gợi ý trong Python liên quan đến một đại tràng và một loại khai báo sau khi gọi một tên đầu tiên trong một không gian tên. Một ví dụ:
name: str age: int name = input["Your name?"] age = int[input["Your age?"]]
Các tuyên bố đầu tiên của
name: int age: int name = input["Your name?"] age = int[input["Your age?"]]0 và
name: int age: int name = input["Your name?"] age = int[input["Your age?"]]1 với gợi ý loại đảm bảo rằng bất kỳ việc sử dụng tên nào trong tương lai trong không gian tên đó sẽ được kiểm tra so với các loại đó. Chẳng hạn, mã này sẽ không hợp lệ:
name: int age: int name = input["Your name?"] age = int[input["Your age?"]]
Bởi vì chúng tôi đã tuyên bố ____10 là
name: int age: int name = input["Your name?"] age = int[input["Your age?"]]3 rồi và
name: int age: int name = input["Your name?"] age = int[input["Your age?"]]4 theo mặc định trả về một chuỗi, trình kiểm tra loại sẽ phàn nàn.
Các hệ thống kiểm tra loại Python sẽ, bất cứ khi nào có thể, cố gắng suy ra các loại. Chẳng hạn, hãy để nói rằng chúng tôi đã sử dụng mã sau mà không có khai báo loại trước:
name = input["Your name?"] age = int[input["Your age?"]]
Trong trường hợp đó, trình kiểm tra loại sẽ có thể suy ra rằng
name: int age: int name = input["Your name?"] age = int[input["Your age?"]]0 là một chuỗi [vì
name: int age: int name = input["Your name?"] age = int[input["Your age?"]]6 không trả lại bất cứ điều gì khác] và
name: int age: int name = input["Your name?"] age = int[input["Your age?"]]1 là một
name: int age: int name = input["Your name?"] age = int[input["Your age?"]]3 [vì
name: int age: int name = input["Your name?"] age = int[input["Your age?"]]9 không trả lại bất cứ điều gì khác]. Nhưng kết quả tốt nhất đến từ việc gợi ý từng biến một cách rõ ràng.
Nhập các chức năng Python
Các hàm Python cũng có thể được loại gợi ý, để các giá trị mà chúng chấp nhận và trả về được ghi lại trước thời hạn. Xem xét mã sau:
greeting = "Hello, {}, you're {} years old" def greet[user, age]: return greeting.format[user, age] name = input["Your name?"] age = int[input["How old are you?"]] print[greet[name, age]]
Một sự mơ hồ với mã này là về lý thuyết
name = input["Your name?"] age = int[input["Your age?"]]0 có thể chấp nhận bất kỳ loại nào cho
name = input["Your name?"] age = int[input["Your age?"]]1 và
name: int age: int name = input["Your name?"] age = int[input["Your age?"]]1 và có thể trả về bất kỳ loại nào. Đây là cách chúng ta có thể định hướng điều đó với các gợi ý loại:
greeting = "Hello, {}, you're {} years old" def greet[user:str, age:int] -> str: return greeting.format[user, age] name = input["Your name?"] age = int[input["How old are you?"]] print[greet[name, age]]
Với các gợi ý loại này cho
name = input["Your name?"] age = int[input["Your age?"]]0, trình soạn thảo của bạn có thể cho bạn biết trước loại nào
name = input["Your name?"] age = int[input["Your age?"]]0 sẽ chấp nhận khi bạn chèn cuộc gọi vào mã của mình.
Một lần nữa, đôi khi Python có thể tự động suy ra những loại được trả về từ một hàm, nhưng nếu bạn có kế hoạch sử dụng kiểu gợi ý loại với một chức năng, thì tốt nhất là hãy gợi ý mọi thứ về nó - những loại nó có trong các loại cũng như loại nào.
Nhập các đối tượng container gợi ý
Bởi vì các đối tượng như danh sách, từ điển và bộ dữ liệu chứa các đối tượng khác, đôi khi chúng ta sẽ muốn gõ gợi ý chúng để chỉ ra các loại đối tượng mà chúng chứa. Đối với điều này, chúng ta cần chuyển sang mô -đun Python từ
name = input["Your name?"] age = int[input["Your age?"]]5, cung cấp các công cụ để mô tả các loại như vậy sẽ giữ.
from typing import Dict, List dict_of_users: Dict[int,str] = { 1: "Jerome", 2: "Lewis" } list_of_users: List[str] = [ "Jerome", "Lewis" ]
Từ điển được làm bằng các khóa và giá trị, có thể thuộc các loại khác nhau. Bạn có thể mô tả các loại cho một từ điển bằng cách cung cấp chúng như một danh sách cho
name = input["Your name?"] age = int[input["Your age?"]]6. Và bạn có thể mô tả loại đối tượng cho một danh sách bằng cách cung cấp loại đó cho
name = input["Your name?"] age = int[input["Your age?"]]7.
Các loại name = input["Your name?"]
age = int[input["Your age?"]]
8 và name = input["Your name?"]
age = int[input["Your age?"]]
9
Một số đối tượng có thể chứa một trong một vài loại đối tượng khác nhau. Trong những trường hợp này, bạn có thể sử dụng
name = input["Your name?"] age = int[input["Your age?"]]9 hoặc
name = input["Your name?"] age = int[input["Your age?"]]8. Sử dụng
name = input["Your name?"] age = int[input["Your age?"]]9 để chỉ ra rằng một đối tượng có thể là một trong nhiều loại. Sử dụng
name = input["Your name?"] age = int[input["Your age?"]]8 để chỉ ra rằng một đối tượng là một loại đã cho hoặc
greeting = "Hello, {}, you're {} years old" def greet[user, age]: return greeting.format[user, age] name = input["Your name?"] age = int[input["How old are you?"]] print[greet[name, age]]4. Ví dụ:
from typing import Dict, Optional, Union dict_of_users: Dict[int, Union[int,str]] = { 1: "Jerome", 2: "Lewis", 3: 32 } user_id: Optional[int] user_id = None # valid user_id = 3 # also vald user_id = "Hello" # not valid!
Trong trường hợp này, chúng tôi có một từ điển lấy
name: int age: int name = input["Your name?"] age = int[input["Your age?"]]3 làm khóa, nhưng
name: int age: int name = input["Your name?"] age = int[input["Your age?"]]3 hoặc
greeting = "Hello, {}, you're {} years old" def greet[user, age]: return greeting.format[user, age] name = input["Your name?"] age = int[input["How old are you?"]] print[greet[name, age]]7S làm giá trị. Biến
greeting = "Hello, {}, you're {} years old" def greet[user, age]: return greeting.format[user, age] name = input["Your name?"] age = int[input["How old are you?"]] print[greet[name, age]]8 [mà chúng ta có thể sử dụng để so sánh với các khóa từ điển] có thể là một
name: int age: int name = input["Your name?"] age = int[input["Your age?"]]3 hoặc
greeting = "Hello, {}, you're {} years old" def greet[user, age]: return greeting.format[user, age] name = input["Your name?"] age = int[input["How old are you?"]] print[greet[name, age]]4 [không có người dùng hợp lệ], nhưng không phải là
greeting = "Hello, {}, you're {} years old" def greet[user, age]: return greeting.format[user, age] name = input["Your name?"] age = int[input["How old are you?"]] print[greet[name, age]]7.
Nhập gợi ý và các lớp học
Để cung cấp gợi ý loại cho các lớp, chỉ cần tham khảo tên của họ giống như bất kỳ loại nào khác:
from typing import Dict class User: def __init__[self, name]: self.name = name users: Dict[int, User] = { 1: User["Serdar"], 2: User["Davis"] } def inspect_user[user:User] -> None: print [user.name] user1 = users[1] inspect_user[user1]
Lưu ý rằng
greeting = "Hello, {}, you're {} years old" def greet[user:str, age:int] -> str: return greeting.format[user, age] name = input["Your name?"] age = int[input["How old are you?"]] print[greet[name, age]]2 có loại trả về
greeting = "Hello, {}, you're {} years old" def greet[user, age]: return greeting.format[user, age] name = input["Your name?"] age = int[input["How old are you?"]] print[greet[name, age]]4 vì nó chỉ đầu ra
greeting = "Hello, {}, you're {} years old" def greet[user:str, age:int] -> str: return greeting.format[user, age] name = input["Your name?"] age = int[input["How old are you?"]] print[greet[name, age]]4S và không trả lại bất cứ điều gì. .
Khi sử dụng gợi ý loại cho các đối tượng tùy chỉnh, đôi khi chúng ta sẽ cần cung cấp một gợi ý loại cho một đối tượng chưa được xác định. Trong trường hợp đó, bạn có thể sử dụng một chuỗi để cung cấp tên đối tượng:
class User: def __init__[self, name:str, address:"Address"]: self.name = name self.address = address # ^ because let's say for some reason we must have # an address for each user class Address: def __init__[self, owner:User, address_line:str]: self.owner = owner self.address_line = address_line
Điều này rất hữu ích nếu bạn có các đối tượng có sự phụ thuộc lẫn nhau, như trong ví dụ trên. Có lẽ có một cách thanh lịch hơn để gỡ rối điều này, nhưng ít nhất bạn có thể cung cấp các gợi ý trước thời gian trong cùng một không gian tên chỉ bằng cách đặt tên của đối tượng.
Serdar Yegulalp là một nhà văn cao cấp tại Infoworld, tập trung vào học máy, container hóa, devops, hệ sinh thái Python và đánh giá định kỳ.
Bản quyền © 2021 IDG Communications, Inc.