鴻蒙版Flutter庫torch_light手電筒功能深度適配

鴻蒙版Flutter庫torch_light手電筒功能深度適配:跨平臺開發者的光明之路

本項目作者:kirk/堅果

適配倉庫地址

作者倉庫:https://github.com/svprdga/torch_light#

在數字化浪潮的推動下,跨平臺開發框架如 Flutter 憑借其高效、便捷的特性,成為了開發者們的寵兒。而鴻蒙系統的崛起,更是為跨平臺開發注入了新的活力。為了助力開發者在鴻蒙生態中快速實現 torch_light來處理設備手電筒的插件功能,本文將深入淺出地為大家解析如何適配 torch_light 三方庫至鴻蒙平臺。

一、適配鴻蒙版 torch_light 三方庫

(一)版本選擇與倉庫簡介

我們先去 pub 上查看最新版本,我們選擇以 0.0.10版本為基礎進行適配。torch_light 是一個簡單的 Flutter 插件來處理設備手電筒的插件,其 GitHub 倉庫為https://github.com/svprdga/torch_light#,我們的目標是將這個插件適配到鴻蒙平臺。

(二)引入背景與使用場景

在 OpenHarmony 北向生態的發展過程中,許多已經適配了 Flutter 的廠商在接入 OpenHarmony 時,都希望能夠繼續使用 torch_light 來實現手電筒功能。因此,我們提供了這個適配方案,采用插件化的適配器模式,幫助生態伙伴快速實現產品化。

本方案適用于已經支持 Flutter 框架的設備在移植到 OpenHarmony 系統過程中,作為一個備選方案。

(三)使用文檔與插件庫使用

適配 OpenHarmony 平臺的詳細使用指導可以參考:Flutter使用指導文檔

在項目中使用該插件庫時,只需在 pubspec.yaml 文件的 dependencies 中新增如下配置:

dependencies:torch_light:git:url: "git@gitcode.com:nutpi/flutter_torch_light.git"path: ""

然后在項目根目錄運行 flutter pub get,即可完成依賴添加

接下來是具體的適配過程。

二、適配過程詳解

(一)準備工作

確保已經配置好了 Flutter 開發環境,具體可參考 Flutter 配置指南。同時,從 官方插件庫 下載待適配的三方插件。本指導書, 以適配 torch_light 為例

image-20250417200546042

(二)插件目錄結構

下載并解壓插件后,我們會看到以下目錄結構:

  • lib :對接 Dart 端代碼的入口,由此文件接收到參數后,通過 channel 將數據發送到原生端。
  • android :安卓端代碼實現目錄。
  • ios :iOS 原生端實現目錄。
  • example :一個依賴于該插件的 Flutter 應用程序,用于說明如何使用它。
  • README.md :介紹包的文件。
  • CHANGELOG.md :記錄每個版本中的更改。
  • LICENSE :包含軟件包許可條款的文件。

(三)創建插件的鴻蒙模塊

在插件目錄下,打開 Terminal,執行以下命令來創建一個鴻蒙平臺的 Flutter 模塊:

flutter create . --org com.svprdga.torchlight --template=plugin --platforms=ohos

步驟:

  1. 用vscode/trae打開剛剛下載好的插件。

  2. 打開Terminal,cd到插件目錄下。

  3. 執行命令flutter create . --template=plugin --platforms=ohos 創建一個ohos平臺的flutter模塊。

第一個問題,修改sdk的版本,適配舊版本。

我們做好修改就好。

(四)在根目錄下添加鴻蒙平臺配置

在項目根目錄的 pubspec.yaml 文件中,添加鴻蒙平臺的相關配置:

name: torch_light
description: A Flutter plugin to check if the device has a torch / flashlight, and to turn it on and off.
version: 1.1.0
homepage: https://davidserrano.io/
repository: https://github.com/svprdga/torch_lightenvironment:sdk: ">=2.17.5 <4.0.0"flutter: ">=2.3.0"dependencies:flutter:sdk: flutterdev_dependencies:flutter_test:sdk: flutterlint: 2.3.0flutter:plugin:platforms:android:package: com.svprdga.torchlightpluginClass: TorchLightPluginios:pluginClass: TorchLightPluginohos:package: com.svprdga.torchlightpluginClass: TorchLightPlugin

(五)編寫鴻蒙插件的原生 ArkTS模塊

1. 創建鴻蒙插件模塊

使用 DevEco Studio 打開鴻蒙項目。

2. 修改相關配置文件

ohos 目錄內的 oh-package.json5 文件中添加 libs/flutter.har 依賴,并創建 .gitignore 文件,添加以下內容以忽略 libs 目錄:

/node_modules
/oh_modules
/local.properties
/.preview
/.idea
/build
/libs
*.har
/.cxx
/.test
/BuildProfile.ets
/oh-package-lock.json5

oh-package.json5 文件內容如下:

{"name": "torch_light","version": "1.0.0","description": "Please describe the basic information.","main": "index.ets","author": "","license": "Apache-2.0","dependencies": {"@ohos/flutter_ohos": "file:./har/flutter.har"}
}

ohos 目錄下創建 index.ets 文件,導出配置:

import TorchLightPlugin from './src/main/ets/components/plugin/TorchLightPlugin';
export default TorchLightPlugin;
3. 編寫 ETS 代碼

文件結構和代碼邏輯可以參考安卓或 iOS 的實現,鴻蒙的 API 文檔可以參考 :https://gitcode.com/openharmony-sig/flutter_packages/tree/master/packages/path_provider/path_provider_android

ohos的api可以參考:https://gitcode.com/openharmony/docs

以下是 TorchLightPlugin.ets 文件的代碼示例:

  private channel: MethodChannel | null = null;private nativeEventIsTorchAvailable: string = "torch_available";private errorIsTorchAvailable: string = "torch_available_error";private nativeEventEnableTorch: string = "enable_torch";private errorEnableTorchExistentUser: string = "enable_torch_error_existent_user";private errorEnableTorch: string = "enable_torch_error";private errorEnableTorchNotAvailable: string = "enable_torch_not_available";private nativeEventDisableTorch: string = "disable_torch";private errorDisableTorchExistentUser: string = "disable_torch_error_existent_user";private errorDisableTorch: string = "disable_torch_error";private errorDisableTorchNotAvailable: string = "disable_torch_not_available";

這里我主要參考的是

三、手電筒使用

手電筒模式的使用是通過操作手機啟用手電筒功能,使設備的手電筒功能持續保持常亮狀態。

在使用相機應用并操作手電筒功能時,存在以下幾種情況說明:

  • 當使用后置攝像頭并設置閃光燈模式FlashMode關閉時,手電筒功能無法啟用。
  • 當使用前置攝像頭時,手電筒可以正常啟用并保持常亮狀態。
  • 從前置攝像頭切換至后置攝像頭時,如果手電筒原本處于開啟狀態,它將會被自動關閉。

詳情請參考Camera API參考。

開發步驟

導入camera接口,接口中提供了相機相關的屬性和方法,導入方法如下。

import { camera } from '@kit.CameraKit';
import { BusinessError } from '@kit.BasicServicesKit';

通過CameraManager類中的isTorchSupported方法,檢測當前設備是否支持手電筒功能。

function isTorchSupported(cameraManager: camera.CameraManager) : boolean {let torchSupport: boolean = false;try {torchSupport = cameraManager.isTorchSupported();} catch (error) {let err = error as BusinessError;console.error('Failed to torch. errorCode = ' + err.code);}console.info('Returned with the torch support status:' + torchSupport);return torchSupport;
}

通過CameraManager類中的isTorchModeSupported方法,檢測是否支持指定的手電筒模式TorchMode。

function isTorchModeSupported(cameraManager: camera.CameraManager, torchMode: camera.TorchMode) : boolean {let isTorchModeSupport: boolean = false;try {isTorchModeSupport = cameraManager.isTorchModeSupported(torchMode);} catch (error) {let err = error as BusinessError;console.error('Failed to set the torch mode. errorCode = ' + err.code);}return isTorchModeSupport;
}

通過CameraManager類中的setTorchMode方法,設置當前設備的手電筒模式。以及通過CameraManager類中的getTorchMode方法,獲取當前設備的手電筒模式。

在使用getTorchMode方法前,需要先注冊監聽手電筒的狀態變化,請參考狀態監聽。

function setTorchModeSupported(cameraManager: camera.CameraManager, torchMode: camera.TorchMode) : void {cameraManager.setTorchMode(torchMode);let isTorchMode = cameraManager.getTorchMode();console.info(`Returned with the torch mode supportd mode: ${isTorchMode}`);
}

狀態監聽

在相機應用開發過程中,可以隨時監聽手電筒狀態,包括手電筒打開、手電筒關閉、手電筒不可用、手電筒恢復可用。手電筒狀態發生變化,可通過回調函數獲取手電筒模式的變化。

通過注冊torchStatusChange事件,通過回調返回監聽結果,callback返回TorchStatusInfo參數,參數的具體內容可參考相機管理器回調接口實例TorchStatusInfo。

function onTorchStatusChange(cameraManager: camera.CameraManager): void {cameraManager.on('torchStatusChange', (err: BusinessError, torchStatusInfo: camera.TorchStatusInfo) => {if (err !== undefined && err.code !== 0) {console.error(`Callback Error, errorCode: ${err.code}`);return;}console.info(`onTorchStatusChange, isTorchAvailable: ${torchStatusInfo.isTorchAvailable}, isTorchActive: ${torchStatusInfo.isTorchActive}, level: ${torchStatusInfo.torchLevel}`);});
}

完整的代碼

import {FlutterPlugin,FlutterPluginBinding,MethodCall,MethodCallHandler,MethodChannel,MethodResult,
} from '@ohos/flutter_ohos';
import { camera } from '@kit.CameraKit';
import { BusinessError } from '@kit.BasicServicesKit';/** TorchLightPlugin **/
export default class TorchLightPlugin implements FlutterPlugin, MethodCallHandler {private channel: MethodChannel | null = null;private channelName = "com.svprdga.torchlight/main";private NATIVE_EVENT_TORCH_AVAILABLE = "torch_available";private NATIVE_EVENT_ENABLE_TORCH = "enable_torch";private NATIVE_EVENT_DISABLE_TORCH = "disable_torch";private cameraManager: camera.CameraManager | undefined = undefined;constructor() {}getUniqueClassName(): string {return "TorchLightPlugin"}onAttachedToEngine(binding: FlutterPluginBinding): void {this.channel = new MethodChannel(binding.getBinaryMessenger(), this.channelName);this.channel.setMethodCallHandler(this)}onDetachedFromEngine(binding: FlutterPluginBinding): void {if (this.channel != null) {this.channel.setMethodCallHandler(null)}}onMethodCall(call: MethodCall, result: MethodResult): void {this.cameraManager=camera.getCameraManager(getContext());switch (call.method) {case this.NATIVE_EVENT_TORCH_AVAILABLE : this.isTorchAvailable(result);      break;case this.NATIVE_EVENT_ENABLE_TORCH :  this.enableTorch(result);      break;case this.NATIVE_EVENT_DISABLE_TORCH :  this.disableTorch(result);      break;}}//檢查設備是否有可用的手電筒isTorchAvailable(result: MethodResult){if(this.cameraManager!==null){registerTorchStatusChange(this.cameraManager!)}result.success(this.cameraManager!==null?isTorchSupported(this.cameraManager!):false);}//啟用手電筒enableTorch(result: MethodResult){if(this.cameraManager!==null){if(isTorchSupported(this.cameraManager!)&&isTorchModeSupported(this.cameraManager!,camera.TorchMode.ON)){setTorchMode(this.cameraManager!,camera.TorchMode.ON)}}result.success(null)}//禁用手電筒disableTorch(result: MethodResult){if(this.cameraManager!==null){if(isTorchSupported(this.cameraManager!)&&isTorchModeSupported(this.cameraManager!,camera.TorchMode.ON)){setTorchMode(this.cameraManager!,camera.TorchMode.OFF)unregisterTorchStatusChange(this.cameraManager!)}}result.success(null)}}
///檢測是否支持手電筒
function isTorchSupported(cameraManager: camera.CameraManager) : boolean {let torchSupport: boolean = false;try {torchSupport = cameraManager.isTorchSupported();} catch (error) {let err = error as BusinessError;console.error('Failed to torch. errorCode = ' + err.code);}console.info('Returned with the torch support status:' + torchSupport);return torchSupport;
}
///檢測是否支持指定的手電筒模式TorchMode
function isTorchModeSupported(cameraManager: camera.CameraManager, torchMode: camera.TorchMode) : boolean {let isTorchModeSupport: boolean = false;try {isTorchModeSupport = cameraManager.isTorchModeSupported(torchMode);} catch (error) {let err = error as BusinessError;console.error('Failed to set the torch mode. errorCode = ' + err.code);}return isTorchModeSupport;
}
//返回設備當前手電筒模式
function getTorchMode(cameraManager: camera.CameraManager): camera.TorchMode | undefined {let torchMode: camera.TorchMode | undefined = undefined;torchMode = cameraManager.getTorchMode();return torchMode;
}function onTorchStatusChange(cameraManager: camera.CameraManager): void {cameraManager.on('torchStatusChange', (err: BusinessError, torchStatusInfo: camera.TorchStatusInfo) => {if (err !== undefined && err.code !== 0) {console.error(`Callback Error, errorCode: ${err.code}`);return;}console.info(`onTorchStatusChange, isTorchAvailable: ${torchStatusInfo.isTorchAvailable}, isTorchActive: ${torchStatusInfo.isTorchActive}, level: ${torchStatusInfo.torchLevel}`);});
}
///設置手電筒模式
function setTorchMode(cameraManager: camera.CameraManager, torchMode: camera.TorchMode): void {try {cameraManager.setTorchMode(torchMode);} catch (error) {// 失敗返回錯誤碼error.code并處理let err = error as BusinessError;console.error(`The setTorchMode call failed. error code: ${err.code}`);}
}
function callback(err: BusinessError, torchStatusInfo: camera.TorchStatusInfo): void {if (err !== undefined && err.code !== 0) {console.error(`Callback Error, errorCode: ${err.code}`);return;}console.info(`onTorchStatusChange, isTorchAvailable: ${torchStatusInfo.isTorchAvailable}, isTorchActive: ${torchStatusInfo.isTorchActive}, level: ${torchStatusInfo.torchLevel}`);
}function registerTorchStatusChange(cameraManager: camera.CameraManager): void {cameraManager.on('torchStatusChange', callback);
}
function unregisterTorchStatusChange(cameraManager: camera.CameraManager): void {cameraManager.off('torchStatusChange');
}

四、編寫 Example

1. 創建 Example 應用

在插件根目錄下創建一個名為 example 的文件夾,用于存放示例應用。在 example 文件夾中,創建一個鴻蒙平臺的 Flutter 應用,用于驗證插件功能。

2. 簽名與運行

使用 Deveco Studio 打開 example > ohos 目錄,單擊 File > Project Structure > Project > Signing Configs,勾選 Automatically generate signature,等待自動簽名完成。然后運行以下命令:

flutter pub getflutter build hap --debug

如果應用正常啟動,說明插件適配成功。如果沒有,歡迎大家聯系堅果派一起支持。

五、總結

通過以上步驟,我們成功地將 torch_light 三方庫適配到了鴻蒙平臺。這個過程涉及到了解插件的基本信息、配置開發環境、創建鴻蒙模塊、編寫原生代碼以及測試驗證等多個環節。希望這篇博客能夠幫助到需要進行 torch_light 鴻蒙適配的開發者們,讓大家在鴻蒙生態的開發中更加得心應手。

六、參考

  • [如何使用Flutter與OpenHarmony通信 FlutterChannel](https://gitcode.com/openharmony-sig/flutter_samples/blob/master/ohos/docs/04_development/如何使用Flutter與OpenHarmony通信 FlutterChannel.md)
  • [開發module](https://gitcode.com/openharmony-sig/flutter_samples/blob/master/ohos/docs/04_development/如何使用混合開發 module.md)
  • 開發package
  • 開發plugin
  • [開發FFI plugin](https://gitcode.com/openharmony-sig/flutter_samples/blob/master/ohos/docs/04_development/開發FFI plugin.md)
  • developing-packages
  • 適配倉庫地址
  • 手電筒

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

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

相關文章

【信息系統項目管理師】一文掌握高項常考題型-項目進度類計算

更多內容請見: 備考信息系統項目管理師-專欄介紹和目錄 文章目錄 一、進度類計算的基本概念1.1 前導圖法1.2 箭線圖法1.3 時標網絡圖1.4 確定依賴關系1.5 提前量與滯后量1.6 關鍵路徑法1.7 總浮動時間1.8 自由浮動時間1.9 關鍵鏈法1.10 資源優化技術1.11 進度壓縮二、基本公式…

深入了解linux系統—— 操作系統的路徑緩沖與鏈接機制

前言 在之前學習當中&#xff0c;我們了解了被打開的文件是如何管理的&#xff1b;磁盤&#xff0c;以及ext2文件系統是如何存儲文件的。 那我們要打開一個文件&#xff0c;首先要先找到這個文件&#xff0c;操作系統又是如何去查找的呢&#xff1f; 理解操作系統搜索文件 …

Docker Hub倉庫介紹

Docker Hub倉庫全解析&#xff1a;從公共市場到私有化部署指南 一、Docker Hub公共鏡像市場 1.1 核心功能解析 全球最大容器鏡像庫&#xff1a;累計托管超500萬鏡像核心服務矩陣&#xff1a; #mermaid-svg-CAMkhmtSWKEUw7z0 {font-family:"trebuchet ms",verdana,a…

redis使用RDB文件恢復數據

設置存盤間隔為120秒且10個key改變數據自動存盤使用RDB文件恢復數據 IP地址主機名192.168.10.170redis170 [rootredis170 ~]# yum install -y redis [rootredis170 ~]# systemctl start redis步驟一&#xff1a;設置存盤間隔為120秒且10個key改變自動存盤 [rootredis170 ~]#…

SpringBoot多環境配置文件切換

resources下application.yml、application-dev.yml、application-prod.yml多個配置文件。 spring:profiles:active: devspring:profiles:active: prod一般都是通過修改spring.profiles.active值來修改加載不同環境的配置信息&#xff0c;可以把切換的dev/prod放到pom.xml文件來…

Java 并發編程高級技巧:CyclicBarrier、CountDownLatch 和 Semaphore 的高級應用

Java 并發編程高級技巧&#xff1a;CyclicBarrier、CountDownLatch 和 Semaphore 的高級應用 一、引言 在 Java 并發編程中&#xff0c;CyclicBarrier、CountDownLatch 和 Semaphore 是三個常用且強大的并發工具類。它們在多線程場景下能夠幫助我們實現復雜的線程協調與資源控…

【Java多線程】多線程狀態下如何安全使用ArrayList以及哈希表

&#x1f50d; 開發者資源導航 &#x1f50d;&#x1f3f7;? 博客主頁&#xff1a; 個人主頁&#x1f4da; 專欄訂閱&#xff1a; JavaEE全棧專欄 多線程安全使用ArrayList 手動加鎖 日常中最常用的方法&#xff0c;使用synchronized進行加鎖&#xff0c;把代碼打包成一份&a…

InnoDB引擎底層解析(二)之InnoDB的Buffer Pool(三)

Buffer Pool 實例 我們上邊說過&#xff0c;Buffer Pool 本質是 InnoDB 向操作系統申請的一塊連續的內存空間&#xff0c;在多線程環境下&#xff0c;訪問 Buffer Pool 中的各種鏈表都需要加鎖處理&#xff0c;在Buffer Pool特別大而且多線程并發訪問特別高的情況下&#xff0…

Netty學習專欄(三):Netty重要組件詳解(Future、ByteBuf、Bootstrap)

文章目錄 前言一、Future & Promise&#xff1a;異步編程的救星1.1 傳統NIO的問題1.2 Netty的解決方案1.3 代碼示例&#xff1a;鏈式異步操作 二、ByteBuf&#xff1a;重新定義數據緩沖區2.1 傳統NIO ByteBuffer的缺陷2.2 Netty ByteBuf的解決方案2.3 代碼示例&#xff1a;…

Vue3逐步拋棄虛擬Dom,React如何抉擇

虛擬DOM&#xff1a;前端界的替死鬼 這玩意兒就是個前端開發的充氣娃娃&#xff01; 你以為它很牛逼&#xff1f;無非是給真DOM當替死鬼&#xff01; 每次數據變&#xff0c;虛擬DOM先擱內存里自嗨一頓&#xff0c;diff算法跟便秘似的算半天&#xff0c;最后才敢碰真DOM。 說白…

分布式鎖總結

文章目錄 分布式鎖什么是分布式鎖&#xff1f;分布式鎖的實現方式基于數據庫(mysql)實現基于緩存(redis)多實例并發訪問問題演示項目代碼(使用redis)配置nginx.confjmeter壓測復現問題并發是1&#xff0c;即不產生并發問題并發30測試,產生并發問題(雖然單實例是synchronized&am…

解決自簽名證書HTTPS告警:強制使用SHA-256算法生成證書

解決自簽名證書HTTPS告警&#xff1a;強制使用SHA-256算法生成證書 一、問題場景 在使用OpenSSL生成和配置自簽名證書時&#xff0c;常遇到以下現象&#xff1a; 瀏覽器已正確導入根證書&#xff08;.pem文件&#xff09;&#xff0c;但訪問HTTPS站點時仍提示不安全連接或證…

線上 Linux 環境 MySQL 磁盤 IO 高負載深度排查與性能優化實戰

目錄 一、線上告警 二、問題診斷 1. 系統層面排查 2. 數據庫層面分析 三、參數調優 1. sync_binlog 參數優化 2. innodb_flush_log_at_trx_commit 參數調整 四、其他優化建議 1. 日志文件位置調整 2. 生產環境核心參數配置模板 3. 突發 IO 高負載應急響應方案 五、…

window 顯示驅動開發-初始化和 DMA 緩沖區創建

若要指示 GPU 支持 GDI 硬件加速&#xff0c;顯示微型端口驅動程序的 DriverEntry 函數實現必須使用指向驅動程序實現的 DxgkDdiRenderKm 函數的指針填充 DRIVER_INITIALIZATION_DATA 結構的 DxgkDdiRenderKm 成員。 DirectX 圖形內核子系統調用 DxgkDdiRenderKm 函數&#xf…

Go語言實戰:使用 excelize 實現多層復雜Excel表頭導出教程

Go 實現支持多層復雜表頭的 Excel 導出工具 目錄 項目介紹依賴說明核心結構設計如何支持多層表頭完整使用示例總結與擴展 項目介紹 在實際業務系統中&#xff0c;Excel 文件導出是一項常見功能&#xff0c;尤其是報表類需求中常見的復雜多級表頭&#xff0c;常規表格組件往…

機器視覺6-halcon高級教程

機器視覺6-halcon高級教程 雙目立體視覺原理視差外極線幾何雙目標定 雙目立體視覺之Halcon標定一&#xff0e;標定結果二.Halcon標定過程1.獲取左右相機圖像中標定板的區域;2.提取左右相機圖像中標定板的MARK點坐標和攝像機外部參數;3.執行雙目標定;4.獲取非標準外極線幾何到標…

板凳-------Mysql cookbook學習 (六)

2025年Pytorch-gpu版本安裝&#xff08;各種情況適用自己的安裝需求&#xff0c;親測絕對有效&#xff0c;示例安裝torch2.6.0&#xff0c;過程詳細面向小白&#xff09;_torch gpu版本-CSDN博客 https://blog.csdn.net/OpenSeek/article/details/145795127 2.2 查錯 import s…

Spring boot和SSM項目對比

目錄對比 springboot目錄 project├─src│ ├─main│ │ ├─java│ │ │ ├─com.example.demo│ │ │ │ ├─config // 存放SpringBoot的配置類│ │ │ │ ├─controller // 存放控制器類│ │ │ │ ├─entity // 存…

《關于潯川社團退出DevPress社區及內容撤回的聲明》

《關于潯川社團退出DevPress社區及內容撤回的聲明》 尊敬的DevPress社區及讀者&#xff1a; 經潯川社團內部決議&#xff0c;我社決定自**2025年5月26日**起正式退出DevPress社區&#xff0c;并撤回所有由我社成員在該平臺發布的原創文章。相關事項聲明如下&#xff1a; …

Python性能優化利器:__slots__的深度解析與避坑指南

核心場景&#xff1a;當需要創建數百萬個屬性固定的對象時&#xff0c;默認的__dict__字典存儲會造成巨大內存浪費。此時__slots__能通過元組結構取代字典&#xff0c;顯著提升內存效率&#xff08;實測節省58%內存&#xff09;&#xff01; 底層原理&#xff1a;為何能節省內…