Python 中的註解

Vaibhav Vaibhav 2023年1月30日
  1. Python 中的變數註解
  2. Python 中的函式註解
Python 中的註解

Python 是一種健壯的動態型別程式語言。它具有類似於編寫簡單英語的簡單語法,並得到大量庫和功能的支援。

一個這樣的特徵是註解。註解是任意 Python 表示式,它授予有關變數資料型別、函式引數和函式返回型別的提示。

註解旨在提高原始碼的可讀性和理解力,並由第三方庫解釋以提供有效且省時的服務,例如語法提示、資料型別檢查、IDE 中的資料型別提示或整合開發環境自動完成程式碼,以及自動化或人工智慧驅動的文件生成。

Python 中有兩種型別的註解:函式註解和變數註解。在本文中,我們將藉助相關示例來討論 Python 中的兩種註解型別。

Python 中的變數註解

變數註解是旨在提供有關 Python 中變數資料型別的詳細資訊的表示式。變數註解具有以下語法。

<variable > : < expression > = < initial value >

註解表示式寫在變數名和它的初始值之間,以冒號或:為字首。讓我們看一些例子來更好地理解這一點。請參考以下 Python 程式碼。

name: str = "Vaibhav"
age: int = 20
language: str = "Python"
student: bool = True
height: float = 5.9
print("name:", name)
print("age:", age)
print("language:", language)
print("student:", student)
print("height:", height)

輸出:

name: Vaibhav
age: 20
language: Python
student: True
height: 5.9

在上面的示例中,我們使用內建的 Python 資料型別來表示表示式。我們還可以使用字串並提供變數的詳細和簡短描述。

下面的 Python 程式碼描述了這一點。

name: "Name of the person" = "Vaibhav"
age: "Age of the person" = 20
language: "Favorite programming language of the person" = "Python"
student: "Is the person a student?" = True
height: "Height of the person in feet" = 5.9
print("name:", name)
print("age:", age)
print("language:", language)
print("student:", student)
print("height:", height)

輸出:

name: Vaibhav
age: 20
language: Python
student: True
height: 5.9

我們可以使用 __annotations___ 屬性來訪問所有註解。

該屬性是一個字典,其中鍵是變數,值是註解表示式。請注意,此屬性將僅提供有關變數而不是函式的詳細資訊。

請參閱以下 Python 程式碼。

name: "Name of the person" = "Vaibhav"
age: "Age of the person" = 20
language: "Favorite programming language of the person" = "Python"
student: "Is the person a student?" = True
height: "Height of the person in feet" = 5.9
print(__annotations__)

輸出:

{'name': 'Name of the person', 'age': 'Age of the person', 'language': 'Favorite programming language of the person', 'student': 'Is the person a student?', 'height': 'Height of the person in feet'}

對於第一個示例,輸出將如下所示。

{'name': < class 'str' > , 'age': < class 'int' > , 'language': < class 'str' > , 'student': < class 'bool' > , 'height': < class 'float' > }

到目前為止,我們只討論了諸如 intfloatstr 之類的原始資料型別。

現在讓我們瞭解如何為諸如 listtuplesetlist 物件等複雜資料型別編寫註解表示式。為此,我們將使用 typing 模組。

typing 模組是 Python 標準庫的一部分。讓我們通過示例瞭解如何將其用於複雜的資料型別。

請參閱以下 Python 程式碼。

from typing import List, Tuple, Set


def user():
    return {"name": "Vaibhav", "username": "vaibhav", "password": "vaibhav"}


class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y


middlewares: List[str] = []
points: Tuple[Point] = tuple([Point(0, 0), Point(1, 1)])
numbers: Set[int] = set([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
users: List[dict] = [user()]
utils: List["function"] = [sum, len, sorted]
pairs: List[List[int]] = [[1, 2], [2, 3], [3, 4]]
print("middlewares:", middlewares, end="\n\n")
print("points:", points, end="\n\n")
print("numbers:", numbers, end="\n\n")
print("utils:", utils, end="\n\n")
print("users:", users, end="\n\n")
print("pairs:", pairs, end="\n\n")
print(__annotations__)

輸出:

middlewares: []

points: (<__main__.Point object at 0x7fc658e454c0>, <__main__.Point object at 0x7fc658cef610>)

numbers: {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

utils: [<built-in function sum>, <built-in function len>, <built-in function sorted>]

users: [{'name': 'Vaibhav', 'username': 'vaibhav', 'password': 'vaibhav'}]

pairs: [[1, 2], [2, 3], [3, 4]]

{'middlewares': typing.List[str], 'points': typing.Tuple[__main__.Point], 'numbers': typing.Set[int], 'users': typing.List[dict], 'utils': typing.List[ForwardRef('function')], 'pairs': typing.List[typing.List[int]]}

typing 模組有 ListTupleSet 分別對應 listtupleset 的類,它們充當它們的通用版本。除了這三個之外,還有其他泛型類,例如 DictFrozenSetDefaultDictOrderedDict

這些泛型類可用於為變數提供註解表示式。在這些類旁邊,在 [] 括號內放置原始資料型別、字串描述、類或來自同一模組的其他通用類。

請注意,它們可用於為函式提供表示式,我們稍後會學習。要了解 typing 模組,請參閱官方文件此處

Python 中的函式註解

函式註解是旨在提供有關 Python 中函式引數資料型別和函式返回值資料型別的詳細資訊的表示式。函式註解具有以下語法。

def function( < parameter > : < expression > , < parameter > : < expression > = < default value > ) -> <expression > :

註解表示式放置在由冒號或 : 分隔的引數旁邊。

如果有任何預設值,則將它們放在註解表示式之後。對於函式的返回型別,函式簽名後跟一個 -> 或箭頭和註解表示式。

請注意,冒號放在最後。讓我們藉助一些相關示例來理解函式註解。

請參閱以下 Python 程式碼。

from typing import List, Tuple


def create_user(name: str, age: int, hobbies: List[str] = []) -> dict:
    return {"name": name, "age": age, "hobbies": hobbies}


def create_users(users: List[Tuple]) -> List[dict]:
    result = []

    for user in users:
        result.append(create_user(name=user[0], age=user[1], hobbies=user[2]))

    return result


u1: dict = create_user("Vaibhav", 20, ["Football", "Video Games"])
data = [
    ("Rick", 40, ["Shooting"]),
    ("Derly", 38, ["Archery", "Tracking"]),
    ("Maggie", 25, []),
    ("Carol", 32, ["Cooking"]),
]
users: List[dict] = create_users(data)
print(u1)
print(users)
print(__annotations__)

輸出:

{'name': 'Vaibhav', 'age': 20, 'hobbies': ['Football', 'Video Games']}
[{'name': 'Rick', 'age': 40, 'hobbies': ['Shooting']}, {'name': 'Derly', 'age': 38, 'hobbies': ['Archery', 'Tracking']}, {'name': 'Maggie', 'age': 25, 'hobbies': []}, {'name': 'Carol', 'age': 32, 'hobbies': ['Cooking']}]
{'u1': <class 'dict'>, 'users': typing.List[dict]}

正如我們所見,create_user() 函式接受三個值,即 nameagehobbies,並返回一個字典或 dict

create_users() 方法接受表示使用者列表的元組列表。此方法返回字典列表。

create_user() 方法的方法呼叫的結果儲存在變數 u1 中,該變數是 dict 型別。並且,對 create_users() 方法的函式呼叫的結果儲存在變數 users 中,該變數的型別為 List[dict]

__annotations__ 屬性只會提供有關變數的詳細資訊。要獲取有關函式的註解詳細資訊,我們可以使用 __annotations__ 屬性。

下面的 Python 程式碼描述了這一點。

from typing import List, Tuple


def create_user(name: str, age: int, hobbies: List[str] = []) -> dict:
    return {"name": name, "age": age, "hobbies": hobbies}


def create_users(users: List[Tuple]) -> List[dict]:
    result = []

    for user in users:
        result.append(create_user(name=user[0], age=user[1], hobbies=user[2]))

    return result


print(create_user.__annotations__)
print(create_users.__annotations__)

輸出:

{'name': <class 'str'>, 'age': <class 'int'>, 'hobbies': typing.List[str], 'return': <class 'dict'>}
{'users': typing.List[typing.Tuple], 'return': typing.List[dict]}

輸出字典將包含所有註解詳細資訊。請注意,對於返回型別,return 是字典中的鍵。對於引數,引數名稱是關鍵。

作者: Vaibhav Vaibhav
Vaibhav Vaibhav avatar Vaibhav Vaibhav avatar

Vaibhav is an artificial intelligence and cloud computing stan. He likes to build end-to-end full-stack web and mobile applications. Besides computer science and technology, he loves playing cricket and badminton, going on bike rides, and doodling.