本文目錄一覽:
- 1、Python中如何禁止導入某個模塊
- 2、Python的錯誤導入已經安裝模塊問題,怎麼解決
- 3、怎麼解決python中模塊名衝突?
- 4、python有緩存模塊嗎
- 5、python程序設計語言的程序可以導入別的模塊
- 6、程序開發中什麼是模塊緩存?
Python中如何禁止導入某個模塊
試試這個:
import sys
blacklist = [‘os’,’datetime’]for mod in blacklist:
i = __import__(mod)
sys.modules[mod] = None
# 嘗試導入模塊import osimport datetime
Python的錯誤導入已經安裝模塊問題,怎麼解決
當遇到無法導入某個python模塊時,可能會是沒有安裝某個模塊,也有可能是某模塊在加載過程中失敗,也有可能是陷入了循環導入的問題。本文詳細解釋了這個問題。
1. 模塊未安裝或者路徑不對
ImportError: No mudule named myModule
有兩種可能,一是該模塊沒有安裝,一般可以用
pip install %module_name%
來解決。注意有時候模塊安裝包名並不等於要導入的模塊名。這種情況下可以通過pip search | list命令來嘗試找到正確的包。
另一種情況就是包雖然安裝了,但當前運行的程序加載的路徑有錯。python運行時將從以下位置嘗試加載python modules:
* 當前目錄
* 環境變量$PYTHONPATH所指示的值,這是一個由「:」分隔的字符串,各個子字符串都是文件系統的一個路徑。
* 標準庫目錄,如dist-site-packages下的模塊。
* 在.pth文件中指定的路徑,如果存在.pth文件的話。
可以使用以下方式來查看python運行時的包含路徑:
?
12
import sysprint(sys.path)
在運行出錯的腳本裝頭部加上這一段代碼,然後在控制台中查看打印出來的python類庫路徑,檢查安裝包是否已包含在上述路徑中。
***可以通過下面的方式將未包含在路徑中的模塊臨時包含進來:***
sys.path.append(“path/to/module”)
另外,還可以在shell窗口中查看當前的python包含路徑:
echo $PYTHONPATH
2. 無法導入已存在的模塊
如果要導入的模塊包含了native代碼,並且native代碼加載(初始化)失敗時,就會導致這種錯誤。使用ssl,
gevent等涉及native的模塊時,如果對應的native程序並未安裝,則會出現這樣的錯誤。
另一種錯誤情況是,使用相對路徑導入時,父模塊還未導入成功。見下面的代碼:
?
12345
main.pymypackage/ __init__.pymymodule.pymyothermodule.py
mymodule.py如下所示:
?
123456789101112
#!/usr/bin/env python3 # Exported functiondef as_int(a): return int(a) # Test function for module def _test(): assert as_int(‘1’) == 1 if __name__ == ‘__main__’: _test()
以及myothermodule代碼如下所示:
?
1234567891011121314
#!/usr/bin/env python3 from .mymodule import as_int # Exported functiondef add(a, b): return as_int(a) + as_int(b) # Test function for module def _test(): assert add(‘1’, ‘1’) == 2 if __name__ == ‘__main__’: _test()
如果執行mypackage/myothermodule,則會報以下錯誤:
Traceback (most recent call last):
File “myothermodule.py”, line 3, in
module
from .mymodule import as_int
SystemError: Parent module
” not loaded, cannot perform relative import
[這篇文章](#Relative imports in
Python 3)給出了更詳細的解答。
3. 循環導入
這種錯誤稱之為”circular (or cyclic) imports”。是python獨有的一種導入錯誤,在象java這樣的語言中就不存在。
假設有如下兩個文件,a.py和b.py:
?
1234567
#a.pyprint “a in”import sysprint “b imported: %s” % (“b” in sys.modules, )import bprint “a out”print b.x
以及:
?
12345
#b.pyprint “b in”import aprint “b out”x = 3
執行python a.py,將得到以下結果:
?
123456789101112131415
$ python a.pya in b imported: Falseb ina inb imported: Truea outTraceback (most recent call last): File “a.py”, line 4, in module import b File “/home/shlomme/tmp/x/b.py”, line 2, in module import aFile “/home/shlomme/tmp/x/a.py”, line 7, in module print b.xAttributeError: ‘module’ object has no attribute ‘x’
出現這種情況的原因是產生了循環導入。循環導入,以及在導入過程中python進行了加鎖操作,最終導致在模塊b未導入完成時就引用了其中的名字。
判斷導入錯誤是否是因為循環導入引起的,主要看堆棧中是否出現兩次重複的導入。比如上述堆棧中a.py出現兩次,因此可以判斷是這個文件引起的循環導入。
要解決這個問題,可以把模塊看成一種資源,對所有要引入的模塊進行編號,再按靜態資源排序法順次導入,就可以避免循環導入。
怎麼解決python中模塊名衝突?
假如你有兩個同名的模塊,那麼你只能導人它們中的一個——默認情況下,Python總是會選擇在模塊搜索路徑sys.path中最左邊的那一項。如果你偏愛的模塊和頂層腳本在同一目錄下,那就不成問題;由於頂層腳本的主目錄總是模塊搜索路徑中的第一項,因此它的內容總是會首先被自動定位。然而對於跨目錄的導入,模塊搜索路徑的線性本質意味着同名的文件會產生衝突。
要修復這一衝突,要麼避免同名文件。如果你需要同時訪問兩個同名的文件,那麼就要把兩個源文件分別放入子目錄中,這樣包導入目錄名稱將使得模塊引用唯一。只要外圍的包目錄名稱是唯一的,你就能訪問同名模塊中的任意一個,或是全部的兩個。注意,如果你不小心為自己的模塊使用了一個名稱,而它碰巧和你需要使用的標準庫模塊的名稱相同,那麼也會出現這一問題。這是因為程序主目錄(或是模塊路徑中靠前的另一個目錄)下的本地模塊會隱藏和替換標準庫模塊。要修復這種覆蓋,要麼避免使用和你需要的另一模塊相同的名稱,要麼把模塊放到一個包目錄下然後使用Python 3.X的包相對導入模型(包相對導入在2.X版本中是一個可選的功能)。在包相對導入模型下,普通導入會跳過包目錄,因此你可以獲取標準庫版本,但在必要時特殊的點號開頭導入語句仍然可以選取同名模塊的本地版本。
python有緩存模塊嗎
從Python 3.2開始,可以使用functools庫中的裝飾器@lru_cache。這是最近使用過的緩存,所以其中的項目沒有到期時間,但作為快速入侵,它非常有用。
from functools import lru_cache
@lru_cache(maxsize=256)def f(x):
return x*xfor x in range(20):
print f(x)for x in range(20):
print f(x)
python程序設計語言的程序可以導入別的模塊
可以。
importmodname。模塊是指一個可以交互使用,或者從另一Python程序訪問的代碼段。只要導入了一個模塊,就可以引用它的任何公共的函數、類或屬性。模塊可以通過這種方法來使用其它模塊的功能。用import語句導入模塊,就在當前的名稱空間(namespace)建立了一個到該模塊的引用.這種引用必須使用全稱,也就是說,當使用在被導入模塊中定義的函數時,必須包含模塊的名字。所以不能只使用funcname,而應該使用modnamefuncname。
一般情況應該使用import,但有幾個例外,1)module文檔告訴你要用from-import的。2)導入一個包組件。需要一個包裏面的某個子模塊,一般用fromA.bimportc比importA.b.c更方便,且不會冒混淆的危險。
程序開發中什麼是模塊緩存?
模塊緩存就在導入時候檢查是否該模塊已經被緩存起來。
1.在導入搜索期間首先會被檢查的地方是 sys.modules。 這個映射起到緩存之前導入的所有模塊的作用(包括其中間路徑)。 因此如果之前導入過 foo.bar.baz,則 sys.modules 將包含 foo, foo.bar 和 foo.bar.baz 條目。 每個鍵的值就是相應的模塊對象。
在入期間,會在 sys.modules 查找模塊名稱,如存在則其關聯的值就是需要導入的模塊,導入過程完成。 然而,如果值為 None,則會引發 ModuleNotFoundError。 如果找不到指定模塊名稱,Python 將繼續搜索該模塊。
2.sys.modules 是可寫的。刪除鍵可能不會破壞關聯的模塊(因為其他模塊可能會保留對它的引用),但它會使命名模塊的緩存條目無效,導致 Python 在下次導入時重新搜索命名模塊。鍵也可以賦值為 None ,強制下一次導入模塊導致 ModuleNotFoundError 。
但是要小心,因為如果你還保有對某個模塊對象的引用,同時停用其在 sys.modules 中的緩存條目,然後又再次導入該名稱的模塊,則前後兩個模塊對象將 不是 同一個。 相反地,importlib.reload() 將重用 同一個 模塊對象,並簡單地通過重新運行模塊的代碼來重新初始化模塊內容
3.在入期間,會在 sys.modules 查找模塊名稱,如存在則其關聯的值就是需要導入的模塊,導入過程完成。 然而,如果值為 None,則會引發 ModuleNotFoundError。 如果找不到指定模塊名稱,Python 將繼續搜索該模塊。
sys.modules 是可寫的。刪除鍵可能不會破壞關聯的模塊(因為其他模塊可能會保留對它的引用),但它會使命名模塊的緩存條目無效,導致 Python 在下次導入時重新搜索命名模塊。鍵也可以賦值為 None ,強制下一次導入模塊導致 ModuleNotFoundError 。
4.在導入搜索期間首先會被檢查的地方是 sys.modules。 這個映射起到緩存之前導入的所有模塊的作用(包括其中間路徑)。 因此如果之前導入過 foo.bar.baz,則 sys.modules 將包含 foo, foo.bar 和 foo.bar.baz 條目。 每個鍵的值就是相應的模塊對象。
在入期間,會在 sys.modules 查找模塊名稱,如存在則其關聯的值就是需要導入的模塊,導入過程完成。 然而,如果值為 None,則會引發 ModuleNotFoundError。 如果找不到指定模塊名稱,Python 將繼續搜索該模塊。
5.sys.modules 是可寫的。刪除鍵可能不會破壞關聯的模塊(因為其他模塊可能會保留對它的引用),但它會使命名模塊的緩存條目無效,導致 Python 在下次導入時重新搜索命名模塊。鍵也可以賦值為 None ,強制下一次導入模塊導致 ModuleNotFoundError 。
但是要小心,因為如果你還保有對某個模塊對象的引用,同時停用其在 sys.modules 中的緩存條目,然後又再次導入該名稱的模塊,則前後兩個模塊對象將 不是 同一個。 相反地,importlib.reload() 將重用 同一個 模塊對象,並簡單地通過重新運行模塊的代碼來重新初始化模塊內容
原創文章,作者:OPQH,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/140301.html