Python 之類型注解

類型注解允許開發者顯式地聲明變量、函數參數和返回值的類型。但是加不加注解對于程序的運行沒任何影響(是非強制的,且類型注解不影響運行時行為),屬于 有了挺好,沒有也行。但是大型項目按照規范添加注解的話,對于后期開發和維護是很有幫助的,畢竟不用回退好幾層去推斷有些變量的類型。

與原生數據類型的區別

特性類型注解原生數據類型
本質僅為代碼中的類型提示信息,不影響代碼運行時的行為實際存儲和操作數據的結構,決定了數據的操作方式和內存占用
作用提高代碼可讀性,輔助靜態類型檢查用于實際的數據存儲和處理
定義方式在變量名后使用冒號和類型名稱進行標注通過賦值語句創建具體的數據對象

為什么用注解

代碼補全

PyCharm 能根據類型注解提供更準確的屬性/方法建議(如知道?y: str?后,輸入?y.?會提示?str?的方法)。

比如我讀取一個 json 文件并 json.load 后進行處理,像下面這種,在調用 data 的 items() 方法時,PyCharm 是沒有方法提示的(畢竟 PyCharm 沒辦法未卜先知,無法提前預測加載后的 data 是什么類型,這也能理解)。

import jsonif __name__ == '__main__':data = json.load(open("data.json", encoding="utf-8"))for key1, value1 in data.items():for key2, value2 in value1.items():print(f"{key1}\t{key2}\t{value2}")

添加注解以后,代碼補全提示就方便多了。?

import json
from typing import Dictif __name__ == '__main__':data: Dict[str, Dict[str, str]]  # 提前添加對 data 的注解data = json.load(open("data.json", encoding="utf-8"))for key1, value1 in data.items():for key2, value2 in value1.items():print(f"{key1}\t{key2}\t{value2}")

類型提示

添加類型注解以后,如果賦值的數據類型和注解聲明的類型不一致的話,PyCharm 會進行提示,能夠一眼洞察類型不符的情況,提前發現錯誤,避免運行時因類型錯誤導致的?TypeError 報錯

維護方便

在多人協作或長期項目中,類型注解降低了理解代碼的門檻,減少因類型混淆導致的 Bug,對于后期維護很有幫助。?

可讀性提高

類型注解明確聲明了參數和返回值的預期類型,使函數接口的語義一目了然。例如?def get_user(id: int) -> User?比未注解的版本更清晰,減少對參數類型的文字描述。

基礎類型注解

Python 內置的基本類型可以直接用于注解。

# 變量注解
name: str = "Alice"
age: int = 30
price: float = 19.99
is_active: bool = True# 函數參數和返回值注解
def greet(name: str) -> str:return f"Hello, {name}"if __name__ == '__main__':name = "Looking"print(type(name))  # <class 'str'>greet_word = greet(name)print(greet_word)  # Hello, Looking

復合類型注解

from typing import List, Dict, Tuple, Set, Optional# 列表
numbers: List[int] = [1, 2, 3]# 字典
person: Dict[str, str] = {"name": "Alice", "email": "alice@example.com"}# 元組 (固定長度和類型)
point: Tuple[float, float] = (3.14, 2.71)# 集合
unique_numbers: Set[int] = {1, 2, 3}# 可選類型 (表示 middle_name 有值的時候是 str,無值的時候可以是 None)
middle_name: Optional[str] = None

函數類型注解

from typing import Callable# 基本函數注解
def add(a: int, b: int) -> int:return a + b# 帶默認值的參數
def greet(name: str, greeting: str = "Hello") -> str:return f"{greeting}, {name}"# 函數作為參數
def apply_func(func: Callable[[int, int], int], x: int, y: int) -> int:return func(x, y)if __name__ == '__main__':v1 = add(1, 2)print(v1)  # 3v2 = greet("Looking")print(v2)  # Hello, Lookingv3 = apply_func(add, 2, 3)print(v3)  # 5

特殊類型注解

from typing import Any, Union, NoReturn, NewType# Any - 任意類型
def log(message: Any) -> None:print(message)# Union - 多個可能的類型
def square(number: Union[int, float]) -> Union[int, float]:return number ** 2# NoReturn - 函數不會正常返回
def fail() -> NoReturn:raise Exception("Something went wrong")UserId = NewType("UserId", int)
if __name__ == '__main__':log(123)  # 123log("hello world")  # hello worldprint(square(5))  # 25print(square(2.5))  # 6.25# UserId("hello")  # 類型檢查不通過print(UserId(12345))  # 12345fail()# Traceback (most recent call last):#   File "E:\lky_project\tmp_project\test.py", line 24, in <module>#     fail()#   File "E:\lky_project\tmp_project\test.py", line 16, in fail#     raise Exception("Something went wrong")# Exception: Something went wrong

類型注解別名

from typing import List, Tuple# 簡單別名
UserId = int# 復雜別名
Point = Tuple[float, float]
Vector = List[float]def distance(point1: Point, point2: Point) -> float:return ((point1[0] - point2[0]) ** 2 + (point1[1] - point2[1]) ** 2) ** 0.5def normalize(vector: Vector) -> Vector:length = sum(x ** 2 for x in vector) ** 0.5return [x / length for x in vector]if __name__ == '__main__':point1 = (3, 4)point2 = (0, 0)print(distance(point1, point2))  # 5.0vector = [3, 4]print(normalize(vector))  # [0.6, 0.8]

泛型類型注解

from typing import TypeVar, Generic, ListT = TypeVar('T')  # 聲明無約束的類型變量class Stack(Generic[T]):def __init__(self) -> None:self.items: List[T] = []def push(self, item: T) -> None:self.items.append(item)def pop(self) -> T:return self.items.pop()if __name__ == '__main__':# 使用int_stack = Stack[int]()  # 初始化實例并指定 T 的類型int_stack.push(12345)print(int_stack.items)  # [12345]str_stack = Stack[str]()str_stack.push("hello")print(str_stack.items)  # ['hello']

類型變量

from typing import TypeVar# 無約束的類型變量(表明 T 可以是無約束的任何類型)
T = TypeVar('T')# 有約束的類型變量
Number = TypeVar('Number', int, float, complex)def double(x: Number) -> Number:return x * 2def triple(x: T) -> T:return x * 3if __name__ == '__main__':print(double(123))  # 246print(triple("hello "))  # hello hello hello

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/905830.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/905830.shtml
英文地址,請注明出處:http://en.pswp.cn/news/905830.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

rocketmq并發消費

netty的handler 在netty的網絡模型中&#xff0c;在想bootstrap設置handler時&#xff0c; 都是在等待 事件 的到來&#xff0c;才會被調用的方法&#xff0c;都是被動的&#xff0c; 服務端等待 request 的到來&#xff0c;進行read, 然后主動調用writeAndFlush寫出去。 客戶…

React 播客專欄 Vol.9|React + TypeScript 項目該怎么起步?從 CRA 到配置全流程

&#x1f44b; 歡迎回到《前端達人 React 播客書單》第 9 期&#xff08;正文內容為學習筆記摘要&#xff0c;音頻內容是詳細的解讀&#xff0c;方便你理解&#xff09;&#xff0c;請點擊下方收聽 你是不是常在網上看到 .tsx 項目、Babel、Webpack、tsconfig、Vite、CRA、ESL…

【PmHub后端篇】PmHub中基于自定義注解和AOP的服務接口鑒權與內部認證實現

1 引言 在現代軟件開發中&#xff0c;尤其是在微服務架構下&#xff0c;服務接口的鑒權和內部認證是保障系統安全的重要環節。本文將詳細介紹PmHub中如何利用自定義注解和AOP&#xff08;面向切面編程&#xff09;實現服務接口的鑒權和內部認證&#xff0c;所涉及的技術知識點…

芯片測試之X-ray測試

原理&#xff1a; X-ray是利用陰極射線管產生高能量電子與金屬靶撞擊&#xff0c;在撞擊過程中&#xff0c;因電子突然減速&#xff0c;其損失的動能會以X-Ray形式放出。而對于樣品無法以外觀方式觀測的位置&#xff0c;利用X-Ray穿透不同密度物質后其光強度的變化&#xff0c;…

QBasic 一款古老的編程語言在現代學習中的價值(附程序)

QBasic&#xff08;Quick Beginner’s All-purpose Symbolic Instruction Code&#xff09;是微軟公司于 1991 年推出的一款簡單易學的編程語言&#xff0c;作為BASIC語言的變種&#xff0c;它曾廣泛應用于教育領域和初學者編程入門。盡管在當今Python、Java等現代編程語言主導…

【八股戰神篇】Java高頻基礎面試題

1 面向對象編程有哪些特性&#xff1f; 面向對象編程&#xff08;Object-Oriented Programming&#xff0c;簡稱 OOP&#xff09;是一種以對象為核心的編程范式&#xff0c;它通過模擬現實世界中的事物及其關系來組織代碼。OOP 具有三大核心特性&#xff1a;封裝、繼承、多態。…

科學養生指南:解鎖健康生活新方式

在快節奏的現代生活中&#xff0c;健康養生成為人們關注的焦點。想要擁有良好的身體狀態&#xff0c;無需依賴復雜的傳統理論&#xff0c;通過科學的生活方式&#xff0c;就能輕松實現養生目標。? 規律運動是健康的基石。每周進行 150 分鐘以上的中等強度有氧運動&#xff0c…

OpenCV閾值處理完全指南:從基礎到高級應用

引言 閾值處理是圖像處理中最基礎、最常用的技術之一&#xff0c;它能夠將灰度圖像轉換為二值圖像&#xff0c;為后續的圖像分析和處理奠定基礎。本文將全面介紹OpenCV中的各種閾值處理方法&#xff0c;包括原理講解、代碼實現和實際應用場景。 一、什么是閾值處理&#xff1…

Java8到24新特性整理

本文整理了 Java 8 至 Java 24 各版本的新特性&#xff0c;內容包括每個版本的新增功能分類&#xff08;如語法增強、性能優化、工具支持等&#xff09;、詳細的代碼示例&#xff0c;并結合官方文檔資料&#xff0c;分析每項特性的應用場景及優缺點。Java 8 發布于 2014 年&…

輪詢仲裁器

參考視頻 https://www.bilibili.com/video/BV1VQ4y1w7Rr/?spm_id_from333.337.search-card.all.click&vd_sourceaedd69dc9740e91cdd85c0dfaf25304b 算法原理

Armijo rule

非精線搜索步長規則Armijo規則&Goldstein規則&Wolfe規則_armijo rule-CSDN博客 [原創]用“人話”解釋不精確線搜索中的Armijo-Goldstein準則及Wolfe-Powell準則 – 編碼無悔 / Intent & Focused

力扣HOT100之二叉樹:102. 二叉樹的層序遍歷

這道題太簡單了&#xff0c;相當于基礎的模板題&#xff0c;但凡涉及到層序遍歷一定會用到隊列來實現&#xff0c;其他的倒沒啥好說的&#xff0c;用兩層while循環來層序遍歷&#xff0c;外層while循環用于控制訪問二叉樹的每一層&#xff0c;而內層while循環則負責收割每一層的…

Ubuntu24.04 安裝 5080顯卡驅動以及cuda

前言 之前使用Ubuntu22.04版本一直報錯,然后換了24.04版本才能正常安裝 一. 配置基礎環境 Linux系統進行環境開發環境配置-CSDN博客 二. 安裝顯卡驅動 1.安裝驅動 按以下步驟來&#xff1a; sudo apt update && sudo apt upgrade -y#下載最新內核并安裝 sudo add…

WAS和Tomcat的對比

一、WAS和Tomcat的對比 WebSphere Application Server (WAS) 和 Apache Tomcat 是兩款常用的 Java 應用服務器&#xff0c;但它們有許多顯著的區別。在企業級應用中&#xff0c;它們扮演不同的角色&#xff0c;各自有其特點和適用場景。以下是它們在多個維度上的詳細對比&…

asp.net IHttpHandler 對分塊傳輸編碼的支持,IIs web服務器后端技術

IHttpHandler&#xff0c;不支持分塊傳輸編碼&#xff08;Chunked Transfer&#xff09;吧&#xff1f; IHttpHandler 對分塊傳輸編碼的支持 實際上&#xff0c;IHttpHandler 完全支持分塊傳輸編碼&#xff08;Chunked Transfer Encoding&#xff09;&#xff0c;但具體行為取…

為什么elasticsearch配置文件JVM配置31G最佳

Elasticsearch的JVM堆內存配置為32GB被視為最佳實踐&#xff0c;主要基于以下綜合技術原理和性能優化考量&#xff1a; 1. ?JVM指針壓縮機制優化內存效率? 當堆內存≤32GB時&#xff0c;JVM啟用?對象指針壓縮&#xff08;Compressed Ordinary Object Pointers, COOP&#…

Systemd基礎

1. 概述 Systemd 是一系列工具的集合&#xff0c;其作用也遠遠不僅是啟動操作系統&#xff0c;它還接管了后臺服務、結束、狀態查詢&#xff0c;以及日志歸檔、設備管理、電源管理、定時任務等許多職責&#xff0c;并支持通過特定事件&#xff08;如插入特定 USB 設備&#xf…

AI預測3D新模型百十個定位預測+膽碼預測+去和尾2025年5月16日第79彈

從今天開始&#xff0c;咱們還是暫時基于舊的模型進行預測&#xff0c;好了&#xff0c;廢話不多說&#xff0c;按照老辦法&#xff0c;重點8-9碼定位&#xff0c;配合三膽下1或下2&#xff0c;殺1-2個和尾&#xff0c;再殺6-8個和值&#xff0c;可以做到100-300注左右。 (1)定…

CentOS高手之路:從進階實戰到企業級優化

一、系統深度優化與性能調優 1. 內核參數調優 通過修改/etc/sysctl.conf文件調整內核參數&#xff0c;可顯著提升服務器性能。例如&#xff1a; net.ipv4.tcp_fin_timeout30&#xff08;快速釋放TCP連接&#xff09; vm.swappiness10&#xff08;減少交換分區使用&#xff0…

Docker 無法拉取鏡像解決辦法

問題 在linux終端中通過 docker pull 命令拉取鏡像&#xff0c;報錯無法拉取鏡像&#xff0c;這是因為 Docker 客戶端無法連接到 Docker 鏡像倉庫&#xff08;Docker Hub&#xff09; 解決方法 1、配置國內可用的 Docker鏡像加速器&#xff0c;這些鏡像加速器用于提高從Docke…