- 在Python中定续,一個.py文件就稱之為一個模塊(Module)
- 使用模塊還可以避免函數(shù)名和變量名沖突租漂。相同名字的函數(shù)和變量完全可以分別存在不同的模塊中,因此,我們自己在編寫模塊時士骤,不必考慮名字會與其他模塊沖突
- 為了避免模塊名沖突,Python又引入了按目錄來組織模塊的方法蕾域,稱為包(Package)
- 舉個例子拷肌,一個abc.py的文件就是一個名字叫abc的模塊,一個xyz.py的文件就是一個名字叫xyz的模塊旨巷。
-
現(xiàn)在巨缘,假設(shè)我們的abc和xyz這兩個模塊名字與其他模塊沖突了,于是我們可以通過包來組織模塊采呐,避免沖突若锁。方法是選擇一個頂層包名,比如mycompany斧吐,按照如下目錄存放
- 引入了包以后又固,只要頂層的包名不與別人沖突仲器,那所有模塊都不會與別人沖突。現(xiàn)在仰冠,abc.py模塊的名字就變成了mycompany.abc乏冀,類似的,xyz.py的模塊名變成了mycompany.xyz
- 請注意洋只,每一個包目錄下面都會有一個init.py的文件辆沦,這個文件是必須存在的,否則识虚,Python就把這個目錄當成普通目錄肢扯,而不是一個包。init.py可以是空文件担锤,也可以有Python代碼蔚晨,因為init.py本身就是一個模塊,而它的模塊名就是mycompany
-
類似的妻献,可以有多級目錄,組成多級層次的包結(jié)構(gòu)
- 文件www.py的模塊名就是mycompany.web.www团赁,兩個文件utils.py的模塊名分別是mycompany.utils和mycompany.web.utils
使用模塊
我們以內(nèi)建的sys模塊為例育拨,編寫一個hello的模塊:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 第4行是一個字符串,表示模塊的文檔注釋欢摄,任何模塊代碼的第一個字符串都被視為模塊的文檔注釋
' a test module '
# 第6行使用__author__變量把作者寫進去熬丧,這樣當你公開源代碼后別人就可以瞻仰你的大名
__author__ = 'Michael Liao'
# 以上就是Python模塊的標準文件模板,當然也可以全部刪掉不寫怀挠,但是析蝴,按標準辦事肯定沒錯
# 導入sys模塊后,我們就有了變量sys指向該模塊绿淋,利用sys這個變量闷畸,就可以訪問sys模塊的所有功能
import sys
def test():
args = sys.argv
if len(args)==1:
print('Hello, world!')
elif len(args)==2:
print('Hello, %s!' % args[1])
else:
print('Too many arguments!')
if __name__=='__main__':
test()
# sys模塊有一個argv變量,用list存儲了命令行的所有參數(shù)吞滞。argv至少有一個元素佑菩,因為第一個參數(shù)永遠是該.py文件的名稱,例如:
# 運行python3 hello.py獲得的sys.argv就是['hello.py']裁赠;
# 運行python3 hello.py Michael獲得的sys.argv就是['hello.py', 'Michael]
# 當我們在命令行運行hello模塊文件時殿漠,Python解釋器把一個特殊變量__name__置為__main__,而如果在其他地方導入該hello模塊時佩捞,if判斷將失敗绞幌,因此,這種if測試可以讓一個模塊通過命令行運行時執(zhí)行一些額外的代碼一忱,最常見的就是運行測試
# 可以用命令行運行hello.py看看效果:
$ python3 hello.py
Hello, world!
$ python hello.py Michael
Hello, Michael!
# 如果啟動Python交互環(huán)境莲蜘,再導入hello模塊:
$ python3
Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 23 2015, 02:52:03)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import hello
>>>
# 導入時谭确,沒有打印Hello, word!,因為沒有執(zhí)行test()函數(shù)菇夸。
# 調(diào)用hello.test()時琼富,才能打印出Hello, word!:
>>> hello.test()
Hello, world!
作用域
- 在一個模塊中,我們可能會定義很多函數(shù)和變量庄新,但有的函數(shù)和變量我們希望給別人使用鞠眉,有的函數(shù)和變量我們希望僅僅在模塊內(nèi)部使用。在Python中择诈,是通過_前綴來實現(xiàn)的
- 正常的函數(shù)和變量名是公開的(public)械蹋,可以被直接引用,比如:abc羞芍,x123哗戈,PI等;
- 類似xxx這樣的變量是特殊變量荷科,可以被直接引用唯咬,但是有特殊用途,比如上面的author畏浆,name就是特殊變量胆胰,hello模塊定義的文檔注釋也可以用特殊變量doc訪問,我們自己的變量一般不要用這種變量名刻获;
- 類似_xxx和__xxx這樣的函數(shù)或變量就是非公開的(private)蜀涨,不應(yīng)該被直接引用,比如_abc蝎毡,__abc等厚柳;
- 之所以我們說,private函數(shù)和變量“不應(yīng)該”被直接引用沐兵,而不是“不能”被直接引用别垮,是因為Python并沒有一種方法可以完全限制訪問private函數(shù)或變量,但是扎谎,從編程習慣上不應(yīng)該引用private函數(shù)或變量宰闰。
安裝第三方模塊
- 在Python中,安裝第三方模塊簿透,是通過包管理工具pip完成的
- 注意:Mac或Linux上有可能并存Python 3.x和Python 2.x移袍,因此對應(yīng)的pip命令是pip3
- 一般來說,第三方庫都會在Python官方的pypi.python.org網(wǎng)站注冊老充,要安裝一個第三方庫葡盗,必須先知道該庫的名稱,可以在官網(wǎng)或者pypi上搜索,比如Pillow的名稱叫Pillow觅够,因此胶背,安裝Pillow的命令就是
pip install Pillow
# 有了Pillow,處理圖片易如反掌喘先。隨便找個圖片生成縮略圖:
>>> from PIL import Image
>>> im = Image.open('test.png')
>>> print(im.format, im.size, im.mode)
PNG (400, 300) RGB
>>> im.thumbnail((200, 100))
>>> im.save('thumb.jpg', 'JPEG')
模塊搜索路徑
# 當我們試圖加載一個模塊時钳吟,Python會在指定的路徑下搜索對應(yīng)的.py文件,如果找不到窘拯,就會報錯
>>> import mymodule
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named mymodule
# 默認情況下红且,Python解釋器會搜索當前目錄、所有已安裝的內(nèi)置模塊和第三方模塊涤姊,搜索路徑存放在sys模塊的path變量中
>>> import sys
>>> sys.path
['', '/Library/Frameworks/Python.framework/Versions/3.4/lib/python34.zip', '/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4', '/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/plat-darwin', '/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/lib-dynload', '/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages']
# 如果我們要添加自己的搜索目錄暇番,有兩種方法
# 一是直接修改sys.path,添加要搜索的目錄
>>> import sys
>>> sys.path.append('/Users/michael/my_py_scripts')
# 這種方法是在運行時修改思喊,運行結(jié)束后失效壁酬。
# 第二種方法是設(shè)置環(huán)境變量PYTHONPATH,該環(huán)境變量的內(nèi)容會被自動添加到模塊搜索路徑中恨课。設(shè)置方式與設(shè)置Path環(huán)境變量類似舆乔。注意只需要添加你自己的搜索路徑,Python自己本身的搜索路徑不受影響剂公。