Python中的包給我提供了很好的代碼組織,類似的功能模塊放在同一個包內,不只代碼結構清晰,並且調用起來也比較方便(能夠用*導入)html
可是,咱們在剛開始使用Python包的時候老是會遇到導入錯誤"ImportError: No module named 'xxx'「,下面咱們來簡單介紹一下如何解決這類問題python
Python中的包就和C#中的dll同樣都是一些模塊(或者類庫)的集合。Python中新建立的包其實只有兩個文件,一個是以包名命名的文件夾和其中的一個__init__.py文件(包的標識,能夠到我以前的文章查看該文件的具體做用 http://www.cnblogs.com/AlwinXu/p/5598543.html )。既然瞭解了包的定義,那麼咱們如何引用包呢?在引用以前咱們須要知道:app
因此,當再次遇到導入錯的時候,咱們只須要檢查以上四點,基本上能解決大部分的問題。spa
首先我建立了包含兩個包的工程,目錄結構以下:code
下面咱們來看一下包導入的各類狀況:htm
Python自帶包能夠直接用import package或者from package import module來進行導入,覺得自帶包都存在於系統包路徑中,能夠經過sys.path來查看:blog
>>> import sys >>> sys.path ['', '/Users/xualvin/anaconda/lib/python35.zip', '/Users/xualvin/anaconda/lib/python3.5',
'/Users/xualvin/anaconda/lib/python3.5/plat-darwin', '/Users/xualvin/anaconda/lib/python3.5/lib-dynload',
'/Users/xualvin/anaconda/lib/python3.5/site-packages',
'/Users/xualvin/anaconda/lib/python3.5/site-packages/Sphinx-1.3.5-py3.5.egg',
'/Users/xualvin/anaconda/lib/python3.5/site-packages/aeosa',
'/Users/xualvin/anaconda/lib/python3.5/site-packages/setuptools-20.3-py3.5.egg']
第三方python包路徑須要添加到sys.path或者複製到已有sys.path中才能夠正常導入。使用sys.path.append("path_to_third_party_packages")進行添加ip
如在上圖包結構中的RootMain.py中導入Pack1,Pack1.SubPack和Pack2中的模塊:pycharm
from Pack1 import * from Pack1.SubPack1 import SubPack1_Module from Pack2 import Pack2_Module Pack1_Module.ModuleInfo() SubPack1_Module.PrintInfo() Pack2_Module.ModuleInfo()
其中Pack1中的__init__.py定義了__all__:it
__all__ = ["SubPack1_Module"]
導入父包中的模塊,好比在Pack1.SubPack1中的SubPack1_Module.py調用Pack1中的Pack1_Module.py模塊:
from Pack1 import Pack1_Module def Pack1Module(): Pack1_Module.ModuleInfo()
好比在Pack1_Module中導入SubPack1中的SubPack1_Module:
from Pack1.SubPack1 import SubPack1_Module def InvokeSubPack1(): SubPack1_Module.PrintInfo()
這部分其實和第三方包的導入相似,咱們須要將兄弟包導入到sys.path中,好比在Pack2中調用Pack1:
首先,在Pack2中導入Pack1的包路徑,在Pack2中的__init__.py中導入(pycharm好像不須要這一步,VS2013的工程須要,不過加上沒有什麼錯):
import sys sys.path.append("/Users/xualvin/Bokeyuan/Pack1")
其次在Pack2中的模塊中調用Pack1,導入方式和Python自帶包同樣:
from Pack1.SubPack1 import SubPack1_Module from Pack1 import Pack1_Module def InvokePack1(): Pack1_Module.ModuleInfo() SubPack1_Module.PrintInfo()
Python中的包導入咱們只須要注意兩點:一是導入的是否是包,二是導入的包路徑是否可以被找到(sys.path或者本工程中),只要平時寫程序的時候多注意,確定能夠避免不少麻煩。