不管是用import還是用from mmmm import *的方式導入模塊,當程序運行之后,回頭在看那個存儲著mmmm.py文件的目錄中(關于[mmmm.py文件可以看上一講](https://github.com/qiwsir/ITArticles/blob/master/BasicPython/223.md)),多了一個文件:
~~~
qw@qw-Latitude-E4300:~/Documents/ITArticles/BasicPython/codes$ ls mmm*
mmmm.py mmmm.pyc
~~~
在這個目錄下面,除了原來的那個mmmm.py之外,又多了一個mmmm.pyc文件,這個文件不是我寫的,是哪里來的呢?
要破開此迷,需要用import的過程說起。
## import的工作流程
import mmmm,并不是僅僅將mmmm.py這個文件裝載到當前位置(文件內),其實是首先進行了一次運算。當mmmm.py被第一次導入的時候,python首先要對其進行編譯,生成擴展名為.pyc的同名文件,然后才執行mmmm模塊的代碼,創建相應的對象等。就如同把大象裝進冰箱,有三步要執行:
1. **搜索**。就是python要能夠找到import的模塊。怎么找到,后面講述。
2. **編譯**。找到模塊文件之后,將其編譯成字節碼,就是那個.pyc文件里面的(關于字節碼,下面會介紹,請繼續閱讀)。注意,不是什么時候都編譯的,只有第一次運行時候才編譯,如果mmmm.py文件改變了,相當于又一個新文件,也會從新編譯。其實就是.pyc文件中有一個時間戳,python會自動檢查這個時間戳,如果它比同名的.py文件時間戳舊,就會從新編譯。否則跳過。當然,如果根本就沒有找到同名的.py源文件,只有字節碼文件.pyc,那么就只能運行這個了。
3. **運行**。這就沒什么好說的了,生米已經淘干凈了,并且放到鍋里,開始加熱了,最后就只能熟飯了。執行就是前面已經編譯的模塊字節碼文件,順理成章要執行了。
## 搜索模塊
一般情況下,python會自動的完成模塊搜索過程。但是,在某些情況下,或許會要求程序員來設定搜索路徑。當import一個模塊后,python會按照下面的順序來找那個將要導入的模塊文件
1. 程序的主目錄。上一講中,在codes這個目錄中運行交互模式,這時候的主目錄就是codes,當在那個交互模式中運行import mmmm的時候,就首先在codes這個目錄中搜索相應的文件(找到.py之后編譯成為.pyc)。當然,后面在網頁編程中,看官會看到,所謂主目錄是可以通過頂層文件設置的目錄。
2. PYTHONPATH目錄。這是一個環境變量設置,如果沒有設置則濾去。如何進行環境變量設置,請看官google啦。
3. 標準庫目錄。已經隨著Python的安裝進入到計算機中的那個。
4. 任何.pth文件的內容。如果有這類文件,最后要在這類文件中搜索一下。這是一個簡單的方法,在.pth文件中,加入有效目錄,使之成為搜索路徑。下圖就是我的計算機上,存放.pth文件的位置以及里面放著的.pth文件
[](https://github.com/qiwsir/ITArticles/blob/master/Pictures/22401.png)
看官也可以自己編寫.pth文件,里面是有關搜索目錄,保存到這里。比如,打開目錄中的easy-install.pth文件,發現的內容:
[](https://github.com/qiwsir/ITArticles/blob/master/Pictures/22402.png)
搜索就是這么一個過程。這里建議看官了解即可,不一定非要進行什么設置,在很多情況下,python都是會自動完成的。特別是初學者,暫且不要輕舉妄動。
## 重載模塊
以mmmm模塊為例(在這里要特別提醒看官:我這樣命名是相當不好滴,只不過是為了惡搞才這樣命名的)。
在一個shell里面,運行了python,并且做了如下操作:
~~~
>>> import mmmm
>>> mmmm.web
'https://qiwsir.github.io'
~~~
下面我再打開一個shell,編輯mmmm.py這個文件,進行適當修改:
[](https://github.com/qiwsir/ITArticles/blob/master/Pictures/22403.png)
保存之后,切換到原來的那個導入了模塊的交互模式:
~~~
>>> mmmm.web
'https://qiwsir.github.io'
~~~
輸出的跟前面的一樣,沒有任何變化,這是為什么呢?
原來,當導入模塊的時候,只會在第一次導入時加載和執行模塊代碼,之后就不會重新加載或重新執行了,如果模塊代碼修改了,但是這里執行的還是修改之前的。
怎么實現代碼修改之后,執行新的呢?一種方式就是退出原來的交互模式,再重新進入,再import mmmm。呵呵,這種方法有點麻煩。Python提供了另外一個函數——reload函數,能夠實現模塊的重新加載(簡稱重載),重載后模塊代碼重新執行。如下繼續:
~~~
>>> reload(mmmm)
<module 'mmmm' from 'mmmm.py'>
>>> mmmm.web
'https://qiwsir.github.io, I am writing a python book on line.'
~~~
這下就顯示修改之后的內容了。
特別提醒注意:
* reload是內置函數
* reload(module),module是一個已經存在的模塊,不是變量名。
- 第零部分 獨上高樓,望盡天涯路
- 嘮叨一些關于Python的事情
- 為什么要開設本欄目
- 第一部分 積小流,至江海
- Python環境安裝
- 集成開發環境(IDE)
- 數的類型和四則運算
- 啰嗦的除法
- 開始真正編程
- 初識永遠強大的函數
- 玩轉字符串(1):基本概念、字符轉義、字符串連接、變量與字符串關系
- 玩轉字符串(2)
- 玩轉字符串(3)
- 眼花繚亂的運算符
- 從if開始語句的征程
- 一個免費的實驗室
- 有容乃大的list(1)
- 有容乃大的list(2)
- 有容乃大的list(3)
- 有容乃大的list(4)
- list和str比較
- 畫圈還不簡單嗎
- 再深點,更懂list
- 字典,你還記得嗎?
- 字典的操作方法
- 有點簡約的元組
- 一二三,集合了
- 集合的關系
- Python數據類型總結
- 深入變量和引用對象
- 賦值,簡單也不簡單
- 坑爹的字符編碼
- 做一個小游戲
- 不要紅頭文件(1): open, write, close
- 不要紅頭文件(2): os.stat, closed, mode, read, readlines, readline
- 第二部分 窮千里目,上一層樓
- 正規地說一句話
- print能干的事情
- 從格式化表達式到方法
- 復習if語句
- 用while來循環
- 難以想象的for
- 關于循環的小伎倆
- 讓人歡喜讓人憂的迭代
- 大話題小函數(1)
- 大話題小函數(2)
- python文檔
- 重回函數
- 變量和參數
- 總結參數的傳遞
- 傳說中的函數條規
- 關于類的基本認識
- 編寫類之一創建實例
- 編寫類之二方法
- 編寫類之三子類
- 編寫類之四再論繼承
- 命名空間
- 類的細節
- Import 模塊
- 模塊的加載
- 私有和專有
- 折騰一下目錄: os.path.<attribute>
- 第三部分 昨夜西風,亭臺誰登
- 網站的結構:網站組成、MySQL數據庫的安裝和配置、MySQL的運行
- 通過Python連接數據庫:安裝python-MySQLdb,連接MySQL
- 用Pyton操作數據庫(1):建立連接和游標,并insert and commit
- 用Python操作數據庫(2)
- 用Python操作數據庫(3)
- python開發框架:框架介紹、Tornado安裝
- Hello,第一個網頁分析:tornado網站的基本結構剖析:improt模塊、RequestHandler, HTTPServer, Application, IOLoop
- 實例分析get和post:get()通過URL得到數據和post()通過get_argument()獲取數據
- 問候世界:利用GAE建立tornado框架網站
- 使用表單和模板:tornado模板self.render和模板變量傳遞
- 模板中的語法:tornado模板中的for,if,set等語法
- 靜態文件以及一個項目框架
- 模板轉義
- 第四部分 暮然回首,燈火闌珊處
- requests庫
- 比較json/dictionary的庫
- defaultdict 模塊和 namedtuple 模塊
- 第五部分 Python備忘錄
- 基本的(字面量)值
- 運算符
- 常用的內建函數
- 擴展閱讀(來自網絡文章)
- 人生苦短,我用Python