人生苦短 我用Python [0x01] 動態加載模塊
背景
程序模塊化是軟件工程里面一個常見的設計思想,在軟件開發也比較常見,可以把代碼解耦,特別是在面對多人同時開發或者需要經常變動升級。我們使用windows常見的dll就是模塊化的一個例子,一個軟件升級功能,可能就只需要升級一些dll文件就可以了,主題程序不用改動,又比如一些新功能可以用模塊的方式加載等,不僅有利于開發者還方便了使用者。
python的動態加載模塊
在python里面,導入一個模塊使用的是
- import 模塊名
python會在sys.path里面尋找匹配名稱的文件(py, pyo, pyc, pyd, so, dll)等文件,我們可以在python里面打印sys.path是些什么目錄
- import sys
- sys.path
- #返回下面內容
- ['', '/usr/lib64/python26.zip', '/usr/lib64/python2.6', '/usr/lib64/python2.6/plat-linux2', '/usr/lib64/python2.6/lib-tk', '/usr/lib64/python2.6/lib-old', '/usr/lib64/python2.6/lib-dynload', '/usr/lib64/python2.6/site-packages', '/usr/lib64/python2.6/site-packages/gtk-2.0', '/usr/lib/python2.6/site-packages', '/usr/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg-info']
在代碼運行目錄下的文件名也可以作為模塊名導入,比如當前目錄下有一個名字叫tools.py的文件,直接在代碼里面import這個文件名導入。import之后的模塊會保存在sys.modules里面
我們可以看到我們剛才加載的tools.py
但是import只能夠加載固定名稱模塊,不能加載動態比如字符串名稱模塊,比如
- str = 'tools'
- import str
- #提示錯誤
- Traceback (most recent call last):
- File "", line 1, in
- ImportError: No module named str
這個時候,我們需要用到__import__,這是一個python的內置函數,import底層其實也是使用了這個函數加載模塊的,我們可以看看
- __import__
- #返回
- str = 'tools'
- __import__(str)
- #返回加載tools.py成功
好了,現在解決了動態加載隨意模塊的問題了,但是距離成功還有一步之遙,在python里面,加載模塊是有緩存的,意思就是說,加載tools.py之后,就算tools.py內容發生改變了,都不會重新加載,還是無法滿足我們實時更新加載模塊的需求。這里有個比較簡單的辦法,可以使得模塊有需要的時候重新加載,回想之前我們說過,python加載后的模塊都回保存在sys.modules里面,我們只需要再重新加載模塊之前,把模塊從sys.modules里面刪除即可。
- del sys.modules['tools']
- __import__('tools')
使用python這樣的特性,我們寫代碼的時候,就可以把經常需要變動的剝離出來成為一個python模塊,需要的時候動態更新然后重新加載到主程序里面,可以***實現不中斷服務升級。
【本文是51CTO專欄機構作者“睿江云EflyCloud”的原創文章,轉載請聯系原作者】