Gợi ý kiểu trong Python là gì

Nhập động, có nghĩa là loại biến chỉ được xác định trong thời gian chạy, giúp Python linh hoạt và thuận tiện

Tuy nhiên, đồng tiền nào cũng có hai mặt. Gõ lộn xộn các biến thường là gốc rễ của các lỗi ẩn. Các chương trình mạnh mẽ…

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

Gợi ý kiểu trong Python là gì
Bởi Serdar Yegulalp

Nhà văn cao cấp, InfoWorld.

Gợi ý kiểu trong Python là gì
những hình ảnh đẹp

Mục lục

Cho xem nhiều hơn

Python được coi là ngôn ngữ “năng động nhưng được gõ mạnh”. Các loại không được liên kết với tên của mọi thứ, nhưng với chính những thứ đó

Điều này làm cho Python trở nên linh hoạt và thuận tiện cho các nhà phát triển, bởi vì bạn không cần phải xác định và theo dõi chặt chẽ các loại biến nếu bạn chỉ tập hợp một tập lệnh nhanh và bẩn. Nhưng đối với các dự án lớn hơn, đặc biệt là các thư viện do bên thứ ba sử dụng, sẽ giúp biết được loại đối tượng nào được liên kết với biến nào

[ Theo dõi các video hướng dẫn về Python thông minh của Serdar Yegulalp để tìm hiểu các thủ thuật Python thông minh trong 5 phút hoặc ít hơn ]

Hiện tại, Python đã có khả năng "chú thích" tên với thông tin loại, ở dạng này hay dạng khác. Với Python3. 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 một công cụ kiểm tra mã hoặc kẻ nói dối, 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 mã tĩnh mà trước đây khó hoặc không thể thực hiện được. 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 ta sẽ khám phá một số ví dụ cơ bản về gợi ý kiểu Python. Nhưng trước tiên chúng ta sẽ làm sáng tỏ một sự hiểu lầm phổ biến về nó là gì và không được dùng để làm gì.

Cách Python sử dụng gợi ý loại (nó không)

Một quan niệm sai lầm quan trọng về gợi ý kiểu 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ả thông tin loại 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 đang sử dụng, chẳng hạn như trong trình chỉnh sửa hoặc IDE của bạn. Nói cách khác, các gợi ý về kiểu của Python dành cho nhà phát triển, không dành cho thời gian chạy

Điều này nghe có vẻ phản trực giác, đặc biệt nếu bạn đã có kinh nghiệm với các ngôn ngữ mà việc khai báo kiểu không phải là tùy chọn. Nhưng nhóm phát triển của Python đã cố gắng làm rõ rằng các gợi ý kiểu không phải là khúc dạo đầu cho việc ngôn ngữ Python cốt lõi trở thành kiểu gõ tĩnh. Chúng 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 ý kiểu Python có thể kịp thời tạo ra một nhánh của ngôn ngữ được gõ tĩnh, có lẽ như 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 ý kiểu (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 ý kiểu gốc của Python để làm điều tương tự

Nhưng những dự án này được coi là phần bổ sung cho ngôn ngữ Python cốt lõi hơn là dấu hiệu cho thấy Python sẽ đi đâu. Mục đích chính của gợi ý kiểu trong Python là cung cấp cho các nhà phát triển cách làm cho mã của họ tự mô tả nhất có thể, vì lợi ích của chính họ và của các nhà phát triển khác

Cú pháp của gợi ý kiểu Python

Gợi ý nhập trong Python liên quan đến dấu hai chấm và khai báo kiểu sau lần gọi tên đầu tiên trong không gian tên. Một ví dụ

name: str
age: int

name = input("Your name?")
age = int(input("Your age?"))

Các khai báo đầ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 các gợi ý về loại đảm bảo rằng mọi việc sử dụng các tên đó trong không gian tên đó trong tương lai sẽ được kiểm tra đối 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 đã khai báo

name: int
age: int

name = input("Your name?")
age = int(input("Your age?"))
0 là một
name: int
age: int

name = input("Your name?")
age = int(input("Your age?"))
3 và theo mặc định,
name: int
age: int

name = input("Your name?")
age = int(input("Your age?"))
4 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 luận các loại. Chẳng hạn, giả sử chúng ta đã sử dụng đoạn mã sau mà không có khai báo kiểu 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ả về bất kỳ thứ 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ả về bất kỳ thứ 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

Gõ gợi ý hàm Python

Các hàm Python cũng có thể được gợi ý kiểu, để các giá trị mà chúng chấp nhận và trả về được ghi lại trước thời hạn. Hãy xem xét đoạn 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ể phân biệt điều đó với các gợi ý về 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))

Đưa ra các gợi ý về 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 lệnh gọi nó vào mã của mình

Một lần nữa, đôi khi Python có thể tự động suy ra kiểu nào được trả về từ một hàm, nhưng nếu bạn dự định sử dụng gợi ý kiểu với một hàm, thì tốt nhất bạn nên gợi ý mọi thứ về nó — kiểu nó nhận vào cũng như kiểu nó trả về

Nhập các đối tượng vùng chứa gợi ý

Bởi vì các đối tượng như danh sách, từ điển và bộ chứa các đối tượng khác, đôi khi chúng ta sẽ muốn gõ gợi ý cho chúng để chỉ ra loại đối tượng nào chúng chứa. Đối với điều này, chúng ta cần chuyển sang mô-đun

name = input("Your name?")
age = int(input("Your age?"))
5 của Python, cung cấp các công cụ để mô tả các loại những thứ như vậy sẽ chứa

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 tạo 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 từ điển bằng cách cung cấp chúng dưới dạng 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

name = input("Your name?") age = int(input("Your age?")) 8 và name = input("Your name?") age = int(input("Your age?")) 9 loại

Một số đối tượng có thể chứa một trong 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 nhất định 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 hoặc là
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))
7 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 của từ điển) có thể là
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 (“người dùng khô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

Để cung cấp gợi ý loại cho các lớp, chỉ cần tham chiếu tên của chúng 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ó kiểu trả về 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))
4 vì nó chỉ xuất ra ____17_______4 và không trả về gì cả. (Ngoài ra, chúng ta thường biến một thứ như vậy thành một phương thức cho lớp, nhưng nó được tách ra riêng ở đây cho hình minh họa này. )

Khi sử dụng gợi ý loại cho các đối tượng tùy chỉnh, đôi khi chúng tôi sẽ cần cung cấp 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 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 hay hơn để gỡ rối vấn đề này, nhưng ít nhất bạn có thể cung cấp các gợi ý trước thời hạn trong cùng một không gian tên chỉ bằng cách đặt tên của đối tượng

Có liên quan

  • con trăn
  • Ngôn ngữ lập trình
  • Phát triển phần mềm

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ỳ

Tại sao nên sử dụng Python gợi ý kiểu?

Gợi ý nhập cải thiện IDE và linters . Chúng làm cho việc lập luận tĩnh về mã của bạn trở nên dễ dàng hơn nhiều. Nhập gợi ý giúp bạn xây dựng và duy trì kiến ​​trúc sạch hơn. Hành động viết các gợi ý về loại buộc bạn phải suy nghĩ về các loại trong chương trình của mình.

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.

Trình kiểm tra kiểu trong Python là gì?

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 điểm mạnh của các 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 được sử dụng giống như các linters, với các chú thích loại bị bỏ qua khi chạy . Cú pháp khá đơn giản.

Khi nào Python thêm gợi ý kiểu?

Gợi ý loại đã được giới thiệu như một tính năng mới trong Python 3. 5 .