Python 類型注解核心用法指南
一、前言
- 在 Python 開發(fā)中,類型注解是提升代碼可讀性、降低維護(hù)成本的低成本手段——它不影響程序運(yùn)行,卻能讓 IDE 實現(xiàn)智能補(bǔ)全、讓同事快速理解代碼邏輯,更是 dataclass、Pydantic 等常用框架的核心依賴。
- Python 作為動態(tài)類型語言,變量、函數(shù)參數(shù)的類型全靠“猜測”,這會帶來三個核心問題:
- 閱讀成本高:需反復(fù)追溯變量用途,才能理解代碼邏輯;
- 調(diào)試成本高:傳參類型錯誤僅在運(yùn)行時暴露,排查耗時;
- 開發(fā)效率低:IDE 無法提供精準(zhǔn)補(bǔ)全,寫代碼全靠記憶。
而類型注解的核心價值,就是給代碼“打標(biāo)簽”——僅做類型提示,不強(qiáng)制校驗,卻能解決上述問題。
二、類型注解核心用法
按使用場景可以劃分為變量的類型注解、函數(shù)類型注解、類的類型注解
2.1 變量類型注解
這是最基礎(chǔ)的用法,覆蓋全局變量、函數(shù)內(nèi)局部變量,語法統(tǒng)一且簡單,重點(diǎn)區(qū)分“有無默認(rèn)值”的差異。
- 無默認(rèn)值的注解(如 age: int)僅存元數(shù)據(jù),不會創(chuàng)建變量,未賦值直接使用會報錯;
- 有默認(rèn)值的注解,同時完成“類型標(biāo)記”和“變量賦值”,變量可正常使用;
- 注解不強(qiáng)制類型匹配(如 age: int = “20” 可運(yùn)行),僅起提示作用。
# 無默認(rèn)值(僅標(biāo)記類型,不創(chuàng)建變量) 變量名: 類型 # 有默認(rèn)值(標(biāo)記類型+賦值,注解與變量共存) 變量名: 類型 = 默認(rèn)值
age:int = 19 # 合法:只聲明類型,不賦值 name: str # 此時變量還不存在,直接用會報錯 # print(name) # NameError # 賦值后,變量才真正存在 name = "張三" print(name) # 正常運(yùn)行
2.2 函數(shù)類型注解
重點(diǎn)標(biāo)注「參數(shù)類型」和「返回值類型」,讓函數(shù)用途、輸入輸出一目了然,減少溝通成本
- 無返回值最好寫 -> None,省略會導(dǎo)致 IDE 提示異常;
*args注解標(biāo)注“元素類型”(如*args: int表示所有可變位置參數(shù)都是整數(shù));**kwargs注解標(biāo)注“值的類型”(如**kwargs: str表示所有關(guān)鍵字參數(shù)的值為字符串);
# 僅參數(shù)注解
def 函數(shù)名(參數(shù)1: 類型, 參數(shù)2: 類型 = 默認(rèn)值):
pass
# 參數(shù)+返回值注解(-> 標(biāo)識返回類型)
def 函數(shù)名(參數(shù)1: 類型, 參數(shù)2: 類型) -> 返回值類型:
passdef add(a: int, b: int) -> int:
return a + b
# 無返回值(必須寫 -> None,不可省略)
def log(msg: str) -> None:
print(f"日志:{msg}")
# 可變參數(shù)注解(指定內(nèi)部元素類型)
def sum_numbers(*args: int, **kwargs: str) -> list[int]:
return list(args)2.3 類的類型注解(dataclass 依賴)
專門用于標(biāo)記「實例屬性」類型,分三種形態(tài),核心區(qū)分“注解”與“類屬性”的關(guān)系,是 dataclass 框架的核心依賴。
- 純注解(如
name: str)不生成類屬性,僅存入__annotations__,用于標(biāo)記未來實例的屬性類型; - 注解+默認(rèn)值(如
email: str | None = None),一行完成“類型標(biāo)記+類屬性賦值”; - dataclass 正是通過讀取
__annotations__,自動生成__init__、__repr__等方法,無需手動編寫; - 實例化后,注解標(biāo)記的屬性會成為實例屬性,優(yōu)先覆蓋同名類屬性。
class 類名:
# 1. 純注解(僅標(biāo)記實例屬性類型,無類屬性)
屬性名1: 類型
# 2. 注解+默認(rèn)值(標(biāo)記類型+創(chuàng)建類屬性,供實例繼承默認(rèn)值)
屬性名2: 類型 = 默認(rèn)值
# 3. 普通類屬性(無注解,不進(jìn)入__annotations__)
屬性名3 = 默認(rèn)值class User:
# 純注解:僅標(biāo)記實例屬性類型,無類屬性
name: str
age: int
# 注解+默認(rèn)值:有類型標(biāo)記,同時創(chuàng)建類屬性(默認(rèn)值)
email: str | None = None # 實例可覆蓋該默認(rèn)值
gender: str = "未知"
# 普通類屬性:無注解,不進(jìn)入__annotations__,所有實例共享
address = "北京"
# 驗證注解存儲(僅包含帶注解的屬性)
print(User.__annotations__)
# 輸出:{'name': str, 'age': int, 'email': str | None, 'gender': str}三、類型注解元數(shù)據(jù)的存儲機(jī)制
Python 會自動將所有類型注解收集到特殊的 __annotations__ 字典中,本質(zhì)是一個普通字典,鍵為注解標(biāo)記的對象名稱(變量名、函數(shù)參數(shù)名、類屬性名等),值為對應(yīng)的類型(如 str、int、list[int] 等),供框架、工具讀取使用。
3.1 不同場景下的元數(shù)據(jù)存儲
注解元數(shù)據(jù)的存儲位置,隨注解場景(變量、函數(shù)、類)不同而有所差異
模塊級變量注解存儲
全局(模塊級)變量的注解,會存儲在當(dāng)前模塊對象的 annotations 字典中
# 模塊級變量注解
name: str = "張三"
age: int = 20
score: float | None = 95.5
# 查看模塊級注解元數(shù)據(jù)
print(__annotations__)
# 輸出:{'name': str, 'age': int, 'score': float | None}函數(shù)注解存儲
函數(shù)的注解(參數(shù)注解、返回值注解),會存儲在函數(shù)對象的 annotations 字典中,同時返回值注解會單獨(dú)對應(yīng)鍵 “return”,參數(shù)注解對應(yīng)各自的參數(shù)名
def add(a: int, b: int) -> int:
return a + b
# 查看函數(shù)注解元數(shù)據(jù)
print(add.__annotations__)
# 輸出:{'a': int, 'b': int, 'return': int}
# 可變參數(shù)注解的存儲
def sum_numbers(*args: int, **kwargs: str) -> list[int]:
return list(args)
print(sum_numbers.__annotations__)
# 輸出:{'args': int, 'kwargs': str, 'return': list[int]}類注解存儲
類內(nèi)的屬性注解(純注解、注解+默認(rèn)值),會存儲在類對象的 annotations 字典中(普通類屬性無注解,不存入);實例對象本身沒有 annotations,其注解信息繼承自所屬類。
class User:
name: str # 純注解
age: int # 純注解
email: str | None = None # 注解+默認(rèn)值
gender: str = "未知" # 注解+默認(rèn)值
address = "北京" # 無注解,不存入
# 查看類的注解元數(shù)據(jù)
print(User.__annotations__)
# 輸出:{'name': str, 'age': int, 'email': str | None, 'gender': str}
# 實例無__annotations__,繼承類的注解信息
u = User()
print(hasattr(u, "__annotations__")) # 輸出:False3.2 關(guān)鍵注意點(diǎn)
__annotations__是動態(tài)可變的:可手動修改該字典,修改后會影響框架、工具對注解的讀?。ú煌扑]手動修改,易造成混亂);- 無默認(rèn)值的變量注解,僅存入
__annotations__,不創(chuàng)建變量(如age: int僅在__annotations__中有記錄,未賦值則變量不存在); - 框架依賴:dataclass、Pydantic 等框架,核心就是通過讀取
__annotations__字典,實現(xiàn)屬性校驗、自動生成方法等功能。
四、常用類型簡寫
| 類型場景 | 注解寫法(3.10+) | 說明 |
|---|---|---|
| 基礎(chǔ)類型 | int/str/bool/float/None | 最常用、最基礎(chǔ)的類型 |
| 聯(lián)合類型 | str | int、str | None | 多類型二選一(3.10+ 語法) |
| 容器類型 | list[int]、dict[str, int] | 列表(整數(shù)元素)、字典(字符串鍵+整數(shù)值) |
| 任意類型 | Any(需導(dǎo)入 from typing import Any) | 不限制類型,盡量少用,避免失去注解意義 |
| 元組類型 | tuple[int, str] | 固定長度、固定元素類型的元組(如 (1, “a”)) |
到此這篇關(guān)于Python 類型注解核心指南的文章就介紹到這了,更多相關(guān)Python 類型注解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python 調(diào)用API接口 獲取和解析 Json數(shù)據(jù)
這篇文章主要介紹了python 如何調(diào)用API接口 獲取和解析 Json數(shù)據(jù),幫助大家更好的理解和使用python,感興趣的朋友可以了解下2020-09-09
python多線程semaphore實現(xiàn)線程數(shù)控制的示例
這篇文章主要介紹了python多線程semaphore實現(xiàn)線程數(shù)控制的示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
Python操作CouchDB數(shù)據(jù)庫簡單示例
這篇文章主要介紹了Python操作CouchDB數(shù)據(jù)庫簡單示例,本文講解了連接服務(wù)器、創(chuàng)建數(shù)據(jù)庫、創(chuàng)建文檔并插入到數(shù)據(jù)庫等操作實例,需要的朋友可以參考下2015-03-03
Keras實現(xiàn)Vision?Transformer?VIT模型示例詳解
這篇文章主要為大家介紹了Keras實現(xiàn)Vision?Transformer?VIT模型示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
python爬取微信公眾號文章圖片并轉(zhuǎn)為PDF
大家好,本篇文章主要講的是python爬取微信公眾號文章圖片并轉(zhuǎn)為PDF,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下2022-02-02

