python任意模塊間采用全局字典來實現借用其他類對象的方法函數來完成任務或數據通信的功能

我們在編寫pthon代碼時,模塊間的數據通信主要采用以下幾種方法:

1、采用全局變量。所有模塊都通過引用全局變量,通過本模塊對此全局變量數據的修改值,其他模塊也能訪問并得到此全局變量的當前值,由于全局變量的不可控性(經常出現訪問的并不是要訪問的變量值),不建議大家編碼時過多使用全局變量。

2、通過定義的類實例化對象。通過對象調用本類對象的當前屬性、方法、函數來得到本類相關數據。此方法限定了只能在定義有類對象的模塊中來使用,有時要時實撐握類對象中的變化數據也較麻煩,需要通計時器或管理線程來定時刷對象屬性數據得到其當前值。對沒有定義類對象的其他模塊要想訪問此類對象的數據,需要通過定義類對象所在的模塊作為中轉站來傳遞數據,可能也很麻煩。

3、采用回調函數來實時得到類對象中的數據,方法是模塊A中定義類B對象時,同時傳入B對象一個A模塊的函數作為B向A實時傳遞數據的回調函數。使用時,代碼運行到B對象模塊某一位置,調用此回調函數,即可實時的將B模塊中的計算數據回傳給了A,讓A模塊再進一步去處理。如B一直在計算數據,并不斷的將計算情況回調給A,A接收到數據后,根據數據不斷的對UI界面進行更新。但同B和A模塊無直接關聯的C模塊想要再得到B模塊的當前數據就處理起來就很復雜。

4、采用pyside或QT模塊定義的類時,可以通過信號槽實時反饋類對象中的數據變化給類對象定義的模塊中。信號槽的使用相對抽象,這里不作舉例。

5、本文根據python的特性,結合以上方式,償試采用一個全局字典變量,此字典變量專門存儲所有可對外公開調用的模塊中的函數方法,對軟件中任意一模塊,不論是否同其他模塊有關聯(如無需定義或引用類對象),均可以通過字典存儲的其他模塊函數來調用此函數。這只是對模塊間調用函數的一個測試,可能不符合標準的程序設計思維,僅供大家參考。

測試代碼分成以下幾個模塊:

main.py:主模塊,用于測試調用各模塊使用全局字典中存儲的類對象函數。

testClass.py: 同main模塊有關聯,在main.py模塊實例化此模塊類對象,以便進行測試

此模塊中也演示了main模塊傳入的回調函數的示例。

otherClass.py:同main.py和testClass.py模塊無任何關聯的模塊,用于調用全局字典中的testClass類對象函數

gdic.py:定義全局字典變量的模塊:

此模塊中有定義有全局字典g_dicFuntion,字典數據格式定義如下:

key為整數ID號,每項字典元素格式為:{ID:[要調用的函數名稱(實際就是地址),[函數參數列表],['所屬模塊文件名','所屬類名','函數功能說明','函數返回值']}

main.py模塊代碼如下:

"""
main.py: python中償試用全局字典調用各類中的函數:用字典存儲函數地址,實現在任意可調用處調用
"""
import time,sys,io,randomfrom gdic import g_dicFuntion,gf_addFunToDic  #從gdic.py中導入公用全局變量和全局函數
from testClass import *                       #有加入字典存儲函數的類
from otherClass import *                      #測試調用加入字典存儲的函數類#本模塊中的用于測試的外部函數   
#【字典key=0=>mani.py中的全局函數test1(id)】 
def test1(id):return f'test1({id})'#當作回調函數用于測試:參數采用*,表示參數數量不限
def test2(*args):print(f'得到其他模塊傳回的值數量={len(args)},參數值={args}')  #本示例回調的兩個數據:x+y+z=24,[1, 3.14, True, 'abc', [4, 5, 6]]for i in range(len(args)):print(args[i])############################################################################
if __name__ == '__main__':"""函數主入口"""global g_dicFuntion        #聲明全局變量#g_dicFuntion[0]=[test1,[1234],['pyTextFun.py','test1(id)','參數:id=整型','返回值:字符串']]                             #方法一:向字典中加入函數信息gf_addFunToDic(keyID=0,funName=test1,lstArgc=[1234],lstInfo=['pyTextFun.py','test1(id)','參數:id=整型','返回值:字符串'])   #推薦:向字典中加入函數信息【ID=0,即字典的key=0】print(g_dicFuntion)curFuntion=g_dicFuntion.get(0,None)print(curFuntion[0](curFuntion[1][0]))#定義CTest類對象1時,同時傳入要回調本模塊用的回調函數名test2cTest_obj1=CTest(9,8,7,test2)           #類對象中的函數self.ctest()保存到全局字典變量中,供其他模塊無差別調用,建議實例化對象的同時,就對此對象要對外公開的函數分配ID并加入到全局字典中gf_addFunToDic(keyID=1,funName=cTest_obj1.ctest,lstArgc=[9,8,7],lstInfo=['classTest.py','ctest(self,x,y,z)','x=整型,y=整型,z=整型','返回值:字符串'])   #向字典中加入函數信息【ID=1】cTest_obj2=CTest(4,5,6)           #CTest第二個實例化對象,方法同上gf_addFunToDic(keyID=2,funName=cTest_obj2.ctest,lstArgc=[4,5,6],lstInfo=['classTest.py','ctest(self,x,y,z)','x=整型,y=整型,z=整型','返回值:字符串'])   #向字典中加入函數信息【ID=2】cTest_obj1.ctest(1,2,3)     #調用對象方法,此方法有回調函數的示例      cOtherObj=otherClass()      #定義第三方類對象,用來調用類CTest的對象ctestObj1等中的函數及方法(注意此方法是針對實例化對象ctestObj1的,不同的類實例化對象的同一方法可以在字典中分別保存(key不同)cOtherObj.use_classTest()   #調用類CTest的實例化對象cTestObj1等的函數ctest(self,x,y,z)del cTest_obj1              #刪除對象cTest_obj1,刪除后,此實例化對象不可用,但對象原占用的內存段可能可執行代碼段可能還存在CTest.isEnabled[0]=False    #不準再使用cTest_obj1對象在字典中key=1的函數了cOtherObj.use_classTest()   #再測試下結果:仍不會報錯,估計此cTest_obj1對象對應的內存段的可執行代碼沒有被更新覆蓋仍可以使用,但不保證代碼運行久了不會出錯,故應在相關代碼中作處理,略

testClass.py模塊代碼如下:

"""
testClass.py:外部類模塊,供pyClassFun.py模塊測試全局字典調用類中函數
"""
from gdic import g_dicFuntion,gf_addFunToDic  #從gdic.py中導入公用全局變量和全局函數#本模塊中的用于測試的外部函數    
def test3(id):return 'test3'
def test4(x,y):return 'test4'#本模塊中的類
class CTest():"""用于測試的類"""objCount=0                 #所有CTest類實例化對象共用的全局變量,使用方法CTest.objCountisEnabled=[]               #本類當前可使用的類對象序號,如類對象被釋放或鎖定,不準再用字典中存儲的類函數地址來調用時,對應下標元素改為Falseglobal g_dicFuntion        #聲明為全局變量def __init__(self,x,y,z,callback=None):          self.x,self.y,self.z=x,y,zself.callback=callback      #類對象定義處同時傳入回調函數#也可以在初始化時就對類中的可供外部調用的函數分配ID,如下行代碼,只適用于實例化一個對象,如實例化多個對象時,ID號的控制將很麻煩#gf_addFunToDic(ID=1,funName=self.ctest,lstArgc=[x,y,z],lstInfo=['classTest.py','ctest(self,x,y,z)','x=整型,y=整型,z=整型','返回值:字符串'])   #向字典中加入函數信息【ID=1】CTest.objCount+=1                    #在其他模塊中每初始化一個新類對象,此數自+1CTest.isEnabled.append(True)   #同時增加一可用狀態開關#【字典key=1=>mani.py中的類實例化對象cTest_obj1】#【字典key=2=>mani.py中的類實例化對象cTest_obj2】def ctest(self,x,y,z):"""類實例化對象的此函數要被外被其他模塊調用,初始化時,已將此函數加入到全局字典中,"""if(self.callback is not None):       #模塊向另一模塊實時傳遞數據方法一:函數回調,前提:定義對象時要傳入回調函數名稱(實際是地址)lstValues=[1,3.14,True,'abc',[4,5,6]]self.callback(x+y+z,lstValues)   #通過回調函數傳回本模塊生成的數據值return f'CTest->ctest(x={x},y={y},z={z}),CTest.isEnabled={CTest.isEnabled},類對象被實例化數量CTest.ID={CTest.objCount},'

otherClass.py模塊代碼如下:

"""
otherClass.py:同main.py和testClass.py無任何關聯的模塊,用于調用全局字典中的testClass類對象函數
"""
from gdic import g_dicFuntion,gf_addFunToDic  #從gdic.py中導入公用全局變量和全局函數class otherClass():"""測試用其他類任意調用全局字典中已保存的類函數的第三方類"""global g_dicFuntion        #聲明為全局變量def __init__(self):passdef use_classTest(self):"""跨模塊用全局字典中保存的函數地址調用函數,不必使用信號槽或逐級調用"""print('\n===模塊otherClass.py中的self.use_classTest函數通過全局字典記錄的函數地址調用其他模塊函數:本例調用classText.ctest(x,y,z)===')curFuntion_1=g_dicFuntion.get(1,None)   #得到classTest模塊中的類CTest實例化對象cTest_obj1的函數ctest(x,y,z)地址,【在字典中:key=1】if(curFuntion_1 is not None):reFun=curFuntion_1[0](curFuntion_1[1][0],curFuntion_1[1][1],curFuntion_1[1][2])print(f'調用字典中保存的KEY={1}的類函數的傳入參數值 = {reFun}\n')  else:print(f'調用字典中保存的KEY={1}的類函數為空,沒有調用成功\n')curFuntion_2=g_dicFuntion.get(2,None)   #得到classTest模塊中的類CTest實例化對象cTest_obj2的函數ctest(x,y,z)地址,【在字典中:key=2】if(curFuntion_2 is not None):reFun=curFuntion_2[0](curFuntion_2[1][0],curFuntion_2[1][1],curFuntion_2[1][2])print(f'調用字典中保存的KEY={2}的類函數的傳入參數值 = {reFun}\n')  else:print(f'調用字典中保存的KEY={2}的類函數為空,沒有調用成功\n')

全局字典變量模塊gdic.py代碼如下:

"""
gdic.py:定義全局變量的模塊
"""
#定義全局變量
g_dicFuntion={}     #全局字典,保存要調用的函數信息{ID:[要調用的函數名稱(實際就是地址),[函數參數列表],['所屬模塊文件名','所屬類名','函數功能說明','函數返回值']}def gf_addFunToDic(keyID,funName,lstArgc,lstInfo):"""向記錄全局函數全局字典變量中加入一項函數記錄"""print(type(keyID).__name__)c=g_dicFuntion.get(keyID,None)if(type(keyID).__name__=='int' and (g_dicFuntion.get(keyID,None)  is  None)):g_dicFuntion[keyID]=[funName,lstArgc,lstInfo]return Trueelse:print('\n!!!!要加入字典的函數keyID不為整數,或字典key(ID)號已存在,需重新指定key(ID)號!!!!\n')raise ValueError('!!!!要加入字典的函數keyID不為整數,或字典key(ID)號已存在,需重新指定key(ID)號!!!!')  #拋出異常"""
全局字典中可對外使用的函數、方法明細表
keyID號    模塊              實例化對象                函數               參數                 返回值         使用時效              調用模塊
0       main.py              無                   test1               id=整數                 字符串          長期       main.py
1       classTest.py   main.py->cTest_obj1   self.use_classTest      x=9,y=8,z=7              字符串         有限     otherClass.py->use_classTest
2       classTest.py   main.py->cTest_obj2   self.use_classTest      x=4,y=5,z=6              字符串         長期     otherClass.py->use_classTest
3
4
5
6
7
8
9
"""

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

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

相關文章

linux 部署 flink 1.15.1 并提交作業

下載 1.15.1 https://flink.apache.org/downloads.html#apache-flink-1151 部署模式分類 會話模式應用模式單作業模式 1、會話模式 先啟動一個集群,保持一個會話,然后通過客戶端提交作業,所有作業都在一個會話執行; 會話模式適合規…

Redis數據量過大的隱患:查詢會變慢嗎?如何避免?

一、Redis數據過多引發的五大隱患(附系統交互圖) #mermaid-svg-X83bpHUu830QXKUt {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-X83bpHUu830QXKUt .error-icon{fill:#552222;}#mermaid-svg-…

網絡與信息安全有哪些崗位:(3)安全運維工程師

安全運維工程師是企業安全防線的 “日常守護者”,既要確保安全設備與系統的穩定運行,又要實時監控潛在威脅,快速響應并處置安全事件,是連接安全技術與業務運營的關鍵角色。其核心價值在于通過常態化運維,將安全風險控制…

魚皮項目簡易版 RPC 框架開發(三)

本文為筆者閱讀魚皮的項目 《簡易版 RPC 框架開發》的筆記,如果有時間可以直接去看原文, 1. 簡易版 RPC 框架開發 前面的內容可以筆者的前面兩個篇筆記 魚皮項目簡易版 RPC 框架開發(一) 魚皮項目簡易版 RPC 框架開發(…

嵌入式Linux:注冊線程清理處理函數

在 Linux 多線程編程中,線程終止時可以執行特定的清理操作,通過注冊線程清理函數(thread cleanup handler)來實現。這類似于使用 atexit() 注冊進程終止處理函數。線程清理函數用于在線程退出時執行一些資源釋放或清理工作&#x…

【Git】Linux-ubuntu 22.04 初步認識 -> 安裝 -> 基礎操作

文章目錄Git 初識Git 安裝Linux-centosLinux-ubuntuWindowsGit 基本操作配置 Git認識工作區、暫存區、版本庫添加文件 -- 場景一查看 .git 文件添加文件 -- 場景二修改文件版本回退撤銷修改情況一:對于工作區的代碼,還沒有 add情況二:已經 ad…

輕量級音樂元數據編輯器Metadata Remote

簡介 什么是 Metadata Remote (mdrm) ? Metadata Remote 是一個基于 Web 的音頻元數據編輯工具,旨在簡化在無頭服務器(即沒有圖形用戶界面的服務器)上編輯音頻文件的元數據。用戶只需使用 Docker 和瀏覽器,無需復雜的…

免費使用|共享服務器上線RTX3080(20GB顯存)

共享服務器也上架GPU啦 生物信息學中有很多用到GPU的場景,例如我們分享過的:利用GPU加速TensorFlow、部署本地DeepSeek,空間轉錄組學習手冊合輯加速。因此多種GPU供大家選擇:RTX5090、4080S、5070顯卡上機。為了讓此前的CPU服務器…

搭建DM數據守護集群

1環境與規劃準備3個kylin 10操作系統的虛擬機,規劃IP、端口、安裝目錄等。說明搭建REALTIME歸檔模式、事務一致性的數據守護名稱項初始主庫機器dm1初始備庫機器dm2監視器機器dmmon外部業務IP192.168.23.129192.168.23.130192.168.23.131內部心跳IP192.168.23.129192…

AUTOSAR進階圖解==>AUTOSAR_SRS_OCUDriver

AUTOSAR OCU驅動程序詳解 AUTOSAR標準輸出比較單元驅動程序架構與實現分析目錄 1. 概述 1.1 OCU驅動程序簡介1.2 功能概述 2. OCU驅動程序架構 2.1 架構圖2.2 層次結構 3. OCU驅動程序組件設計 3.1 組件圖3.2 接口定義 4. OCU驅動程序狀態管理 4.1 狀態圖4.2 狀態轉換 5. OCU驅…

InfluxDB 與 HTTP 協議交互進階(一)

引言 在當今數字化時代,數據處理的高效性和準確性成為了眾多領域關注的焦點。InfluxDB 作為一款開源的時序數據庫,憑借其高性能、易擴展等特性,在時間序列數據處理中占據了重要地位。而 HTTP 協議作為互聯網應用層的核心協議之一&#xff0c…

NAS遠程訪問新解法:OMV與cpolar的技術協同價值

文章目錄前言1. OMV安裝Cpolar2. 配置FTP公網地址3. OMV FTP 配置4. OMV FTP遠程連接前言 當家庭存儲需求突破本地邊界時,傳統NAS方案往往陷入"連接困境":復雜的端口轉發配置、高昂的公網IP成本、以及始終存在的安全顧慮…開源解決方案OMV雖然…

vue 渲染 | 不同類型的元素渲染的方式(vue組件/htmlelement/純 html)

省流總結&#xff1a;&#xff08;具體實現見下方&#xff09; vue 組件 ——》<component :is組件名> htmlelement 元素 ——》 ref 、★ v-for ref 或是 ★ vue 的 nextTick 純 html 結構——》v-html 另外&#xff0c;當數據異步加載時&#xff0c;vue3中如何渲…

Charles中文版深度解析,輕松調試API與優化網絡請求

在現代軟件開發過程中&#xff0c;調試API、捕獲HTTP/HTTPS流量以及優化網絡性能是開發者不可避免的挑戰。特別是在處理復雜的網絡請求和驗證API接口的數據傳輸準確性時&#xff0c;開發者需要一款強大且易于使用的工具。Charles抓包工具憑借其功能強大、界面簡潔、易于操作的特…

【CF】Codeforces Round 1039 (Div. 2) E1 (二分答案求中位數)

E1. Submedians (Easy Version)題目&#xff1a;思路&#xff1a;經典不過加了點東西對于求中位數&#xff0c;我們必然要想到二分答案&#xff0c;具體的&#xff0c;對于所有大于等于 x 的數我們令其奉獻為 1&#xff0c;小于的為 -1&#xff0c;如果存在某段區間的奉獻和大于…

ESP32-S3學習筆記<8>:LEDC的應用

ESP32-S3學習筆記&#xff1c;8&#xff1e;&#xff1a;LEDC的應用1. 頭文件包含2. LEDC的配置2.1 配置定時器2.1.1 speed_mode/設置速度模式2.1.2 duty_resolution/設置占空比分辨率2.1.3 timer_num/選擇定時器2.1.4 freq_hz/設定PWM頻率2.1.5 clk_cfg/選擇LEDC的外設時鐘源2…

網絡安全第14集

前言&#xff1a;小迪安全14集&#xff0c;這集重點內容&#xff1a;0、什么是js滲透測試&#xff1f;在javascript中也存在變量和函數&#xff0c;存在可控變量和函數就有可能存在在漏洞&#xff0c;js開發的web應用和php、java開發的區別是&#xff0c;js能看得到的源代碼&am…

代碼隨想錄算法訓練營第三十三天

LeetCode.62 不同路徑 題目鏈接 不同路徑 題解 class Solution {public int uniquePaths(int m, int n) {// dp表示到達ij有多少條路徑int[][] dp new int[110][110];dp[1][1] 1;for(int i 0;i<m;i){dp[i][0] 1;}for(int j 0;j<n;j){dp[0][j] 1;}for(int i 1;i…

銀行回單OCR識別技術原理

銀行回單OCR&#xff08;光學字符識別&#xff09;技術通過結合圖像處理、模式識別和自然語言處理&#xff08;NLP&#xff09;技術&#xff0c;將紙質或電子版銀行回單中的非結構化文本&#xff08;如賬號、金額、日期等&#xff09;轉化為結構化數據。以下是其核心原理和關鍵…

Day22-二叉樹的迭代遍歷

昨天學習了遞歸遍歷&#xff1a;遞歸就是一次次的把參數壓入棧中&#xff0c;然后返回的時候還是上一次遞歸保存的參數。今天學習迭代遍歷。迭代遍歷就是用棧去模擬保存二叉樹的節點&#xff0c;然后依次去遍歷&#xff0c;只不過要注意棧的后入先出的規則。前序遍歷&#xff1…