”ImportError: No module named t2“---python的import機制+模塊的搜索路徑

一、背景

       最近在學pyhonweb框架Karrigell,下載了源碼之後運行,出現了error:

                                   ImportError:No module named k_target

       在www/index.py裏面importk_target,但是運行的時候出現了上述錯誤,網上查了一下,知道

       是不同目錄下 import模塊或者包的話,需要將模塊或者包的路徑加入到sys.path中。於是使用了

       sys.path.append('e:\Karrigell\karrigell\core')解決了問題。藉此機會又重新學習了一下python

       import機制和搜索路徑。

二、python的import機制

2.1 模塊和包

      模塊化編程使得軟件開發更加靈活,不同的功能可多人協作完成,同時便於代碼複用和後期維護,

      python使用import模塊/包來組織各個模塊,使不同模塊直接可以調用。

     模塊:python中,每個py文件被稱之爲模塊,它可以定義變量,方法和類;

     包:是一個目錄,它可以包含py文件和子目錄,最重要的一點是包一定含有一個__init__.py文件。

      只要模塊或者包所在的目錄在sys.path中,就能使用import 來引用其他模塊內的變量,方法和類。

 2.2 import的過程

    1. Python中所有加載到內存的模塊都放在sys.modules。當import一個模塊時首先會在這個列表中

        查找是否已經加載了此模塊,如果加載了則只是將模塊的名字加入到正在調用import的模塊的

        Local名字空間中。如果沒有加載則從sys.path目錄中按照模塊名稱查找模塊文件,模塊文件可以

       是pypycpyd找到後將模塊載入內存,並加入到sys.modules中,並將名稱導入到當前的

       Local名字空間。若沒有找到,則import沒有效果,運行時出現ImportError:Nomodule named ***.

       所以:                                             import A

                                                                    |

                                                   查看sys.moudles--->找到,導入模塊名字到當前模塊

                                                                    |

                                  沒有找到,則搜索sys.path--->找到,模塊加載到內存,加入sys.moudles

                                                                   |

                                             沒有找到,則import沒有效果

 

    2.每個模塊在內存只有一份,即pyModuleObject對象只有一個,首次import該模塊時加載到內存,

        然後存放在sys.modules裏,其他模塊再引用該模塊的時候,在sys.modules裏面可以直接找到。

 2.3  包的import

       前面已經講了只要有__init__.py,這個目錄都可以稱爲一個包。包下面的子目錄也可以是子包。

       如果查看包的類型importSQLAlchemy type(SQLAlchemy),可以看到其實也是<type'module'>

      所以import包的時候,查找路徑也是sys.path,加載到內存後也會放在sys.modules中。

       import包的時候,需要考慮__init__.py,因爲首次導入包的時候會執行此文件裏面的語句而不是

      模塊裏面的語句,例如執行importpackage;就會執行__init__.py文件,如果想在導入包時做一些

      初始化工作,eg:導入其他的包都可以寫在這個文件裏面。eg:列表__all__=["module1","module2"],

      它包含了執行 from package  import  *時導入的模塊。

 2.4 import的使用

      如果想要引用某個模塊A.py中內容,有兩種方法:

       1.import A; A.func()這實際上是把整個A的代碼在當前環境中執行了一遍,A模塊裏面的變量,

         方法都可以被當前模塊引用

       2.from A import funcfunc();這個是在當前環境中建立和變量func()同名的對象,並且將A中的

          變量賦值給它,直接引用變量或者方法,但是你不能在當前模塊裏面定義同名的變量或者函數。

       注意:import只能模塊,包,而不能直接import變量,函數,類。importA.func()就是錯的。

      如果想要引用某個包B,也有幾種方法:

       1.import B; 想要使用B包下面A模塊的func,B.A.func()-----這時,一定要在__init__裏進行一些

         初始化設定,否則內存中只加載了B,並沒有加載模塊Afunc()調用不到

      2.import B.A ; B.A.func()

      3.from B import A; A.func() from B import *,可以引用所有的模塊

      4.from B.A import func; func()

      5.from B import A as a1;A取了別名

 2.5  import的嵌套

     1. A模塊importB, B模塊importCA中建立了一個local的名字空間BA模塊只能訪問B中的變量

        和函數,而不能訪問C的。如果想訪問C,只能importC

     2. A模塊importBB模塊importA.參考:http://blog.csdn.net/sinat_16790541/article/details/43376741

三、模塊的搜索路徑

      由前面我們知道import模塊的時候,如果模塊沒有在sys.modules裏面,即沒有加載進內存,

      那麼會去sys.path裏面搜索模塊,這裏sys.path就是模塊的搜索路徑,如果看一個模塊能不能

      import成功,就看它是否在sys.path裏面可以找到。

      1. sys.path的第一個選項,是主模塊所以目錄,在交互環境下是一個空項,對應當前目錄。

      2.windows下,若設置了PYTHONPATH,那麼這裏設定的路徑會被自動添加到sys.path裏面,

        所以可以自己添加PYTHONPATH

      3.將自己想要import的模塊或者包的路徑添加到sys.path裏,sys.path.append("路徑名”)

          -------但是這是暫時性的,只要重新運行python,這個路徑就消失了

      4.將自己想要import的模塊或者包放到site_packages目錄下.

        (from distutils.sysconfig import get_python_lib; printget_python_lib()site-packages目錄)

      5.使用pth文件,在site-packages文件中創建.pth文件,將模塊的路徑寫進去,一行一個路徑

      6.將自己想要import的模塊添加到$python_dir/lib


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章