<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
最近有個部署需求,需要讀取py檔案格式的設定項,我的實現思路是把組態檔解析到記憶體中。主要使用兩種方法:
先來看看import module使用方法。
現在開始實現動態導包,成功讀取到設定項。
import importlib settings = importlib.import_module("remote_settings")
這樣子就能初步實現動態倒入了,但是我有個需求,就是我的系統好些個模組,用FOR迴圈導包,然後處理業務。然後問題來了,對同一個“包”匯入多次,python並不會重新匯入,而是返回記憶體快取中該模組的地址。
下面驗證一下,第一次寫入a = 123,第二次寫入a = "hello"。
輸出結果,兩次都是列印舊版本的變數,可見對同一個模組進行多次import_module,並不能實現熱更新。
必須要reload,模組才會更新。
輸出結果如下,動態reload後,成功獲得新版本a的值。
到此基本實現初步熱更新需求了,但是還有個問題:
問題一:重新載入的模組不刪除舊版本在符號表中的登記項,比如舊版本中存在變數a,新版本中刪除了該變數,但是過載不會更新該變化。
def load_module(module_name): module = importlib.import_module(module_name) return importlib.reload(module) def rewrite_file(file_name, content): with open(file_name, "w+") as f: f.write(content) def main(): rewrite_file(file_name, "a=123nb=456") c1 = load_module(module_name) print(hasattr(c1, "a")) rewrite_file(file_name, "c=100nd=200") c1 = load_module(module_name) print(hasattr(c1, "a"))
我們期望輸出 True、False,但是兩次都是輸出True,也就是說重新載入的模組不會刪除最初舊版本模組在符號表中的登記項。
手動建立module物件,而不是使用記憶體中的module物件。這種方法不需要判斷是否需要過載,而且是真正的更新,會刪除舊版本模組的登記項。
import types def import_from_pyfile(filename): d = types.ModuleType("config") # 建立一個模組物件 d.__file__ = filename try: with open(filename, "r") as config_file: exec(compile(config_file.read(), filename, "exec"), d.__dict__) except ImportError as e: print("failt to read config file: {}".format(filename)) raise e return d
下面驗證一下
我們期望的輸出依次是True、False,符合需求
因此,這種方法能讓我們的模組實現真正的過載。
無論是方法1還是方法2,都是返回一個module物件,module物件存在一些共性問題。
問題一:重新載入類不影響類的任何已存範例,已存範例將繼續使用原來的定義,只有重新載入後建立的新範例使用新定義。
# 原先的 Dog 定義 # class Dog(): # def __init__(self): # self.name = None c1 = load_module(module_name) old_dog = c1.Dog() # 中間去修改了 Dog 定義 # class Dog(): # def __init__(self): # self.name = "旺財" c1 = load_module(module_name) new_dog = c1.Dog() print(old_dog.name, new_dog.name) >>> ouput: None 旺財
問題二:模組內的參照,不會被reload。比如模組configA中參照了其他模組(configB),當configB發生變化,重新載入configA,並不會對configB進行過載。
預期應該依次輸出 configB version1、configBversion2,但是輸出了兩次configB version1,這說明了模組內的參照,不會被reload,需要手動更新它。
我這實現了一個遞迴更新方法,不僅對當前模組熱更新,還更新裡面所有的參照。
def load_module(module): if isinstance(module, str): # 首次import module = importlib.import_module(module) return importlib.reload(module) def reload_module(module): load_module(module) for key, child_module in vars(module).items(): if isinstance(child_module, types.ModuleType): reload_module(child_module)
效果如下:
def test_reload_module(): configA = "config" configB = "./configB.py" configC = "./configC.py" rewrite_file(configB, "import configCnname ='configB version1'") rewrite_file(configC, "name ='configC version1'") confA = load_module(configA) print("原始configB.name:", confA.configB.name) print("原始configC.name:", confA.configB.configC.name) a = 123 rewrite_file(configB, "import configCnname ='configB version2'") rewrite_file(configC, "name ='configC version2'") confA = load_module(configA) print("非遞迴過載configA, configB.name:", confA.configB.name) print("非遞迴過載configA, configC.name:", confA.configB.configC.name) reload_module(confA) print("遞迴過載configA, configB.name:", confA.configB.name) print("遞迴過載configA, configC.name:", confA.configB.configC.name)
紀錄檔如下:
到此這篇關於python動態匯入模組,實現模組熱更新的文章就介紹到這了,更多相關python模組熱更新內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45