sys.modules是一個Python解釋器的內置模塊,它是一個字典,維護了系統中所有已經導入模塊的引用。
一、sys.modules 鎖定
在Python中,所有模塊的導入操作都會加載對應的py文件轉換為一個“模塊對象”,並將其存儲在sys.modules中。我們可以通過sys.modules中的字典查找特定模塊,但在多線程環境中,如果兩個或多個線程嘗試同時導入同一個模塊,會有一個線程拿到鎖來解決競爭衝突。此時會出現“模塊鎖定”的問題。
import sys
import threading
import time
def worker():
print('Worker thread started')
time.sleep(1)
module_name = 'math'
if module_name not in sys.modules:
# 模擬模塊導入
__import__(module_name)
print(f'{module_name} has successfully imported')
threads = [threading.Thread(target=worker) for _ in range(5)]
_ = [t.start() for t in threads]
執行代碼段,會導致所有線程中有其中一個線程要進行模塊導入,結束驚喜輸出顯示math模塊只導入了一次,而其他的線程被隔離復用了這個已經導入好的math模塊。這就是因為在主線程和Worker線程都要導入math模塊,由於sys.modules本身是一個字典對象,因此負責導入模塊線程對sys.modules字典的修改可能會被另一個線程圖謀會取回。
二、sys.modules[__name__]
如果在模塊文件中通過命令行直接運行文件,那麼Python會將全局變量__name__的值設置為__main__。如果使用import語句導入這個模塊時,那麼__name__的值就是導入模塊文件名,而不是__main__。在導入模塊時,我們可以使用sys.modules[__name__]來訪問該模塊本身。
# module1.py
import sys
def print_module_name():
print(sys.modules[__name__].__name__)
# main.py
import module1
module1.print_module_name()
執行代碼段,輸出結果為:
module1
三、sys.modules的作用
sys.modules的主要作用是幫助引用已經被導入的Python模塊,避免重複操作。Python機制會在模塊被導入之後將其緩存到sys.modules字典中,並在下一次對其進行訪問時立即返回模塊的引用,從而加速程序的運行效率。在使用時可以直接用模塊名或者sys.modules[module_name]來讀取緩存中的模塊對象,甚至可以從這裡直接刪除一個模塊的緩存,通過重新導入來更新模塊的內容。
四、sys.modules值刪除
Python會在程序進程啟動時自動導入大量模塊,大多數情況下,我們並不需要這些模塊。如果你想清除緩存的sys.modules字典中的所有引用,可以在程序中刪除它,如下所示:
# Clearing all previously imported modules
sys.modules.clear()
五、sys.modules的用法
1. sys.modules.keys()
sys.modules的keys()方法可以返回一個包含所有模塊名的list,即已經被加載到Python解釋器內存中的所有模塊,如:
print(sys.modules.keys())
輸出結果為:
dict_keys(['builtins', '__main__', '_frozen_importlib', '_imp', '_thread', '_warnings', '_weakref', 'sys', '_io', 'marshal', 'posix', 'zipimport', 'encodings', '_codecs', 'codecs', '_sre', 'sre_compile', '_pickle', 'pickle', 'weakref', 'atexit', 'errno', 'fcntl', '_stat', '_collections', 'abc', 'io', 'opcode', 'operator', 'signal', '_signal', 'posixpath', '_posixpath', 'genericpath', 'os', '_sitebuiltins', 'site'])
2. sys.modules tornado
比如我們安裝了tornado模塊,我們可以使用sys.modules[‘tornado’]來訪問tornado包中的內容,如下所示
import sys
sys.modules['tornado'].__version__
輸出結果如下:
'6.1'
3. sys.modules switch
我們可以在Python開發過程中手動切換當前環境中模塊版本。例如,讓我們假設你有兩個版本的requests庫,我們想手動切換版本。可以使用sys.module導入返回的模塊對象,從而啟用不同的版本:
import sys
import requests
sys.modules['requests'] = __import__('requests_', globals(), locals(), ['*'])
注意其中的’new_version’字樣需要替換成你想要導入的版本字符。
六、sys.modules什麼意思
sys.modules實際上是一個存儲當前 Python 解釋用到的所有模塊的字典。Python通常只會在第一次導入時將這些模塊存儲在sys.modules中,以後就可以直接從字典緩存中獲取模塊對象。
sys.modules是一個十分重要的模塊且內置於Python環境,對於熟練使用Python的開發人員而言,它可以幫助我們編寫高效的、更加Pythonic的代碼,提升編碼速度和代碼質量。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/243585.html