W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎勵
在本章之前,python還沒有顯示出太突出的優(yōu)勢。本章開始,讀者就會越來越感覺到python的強(qiáng)大了。這種強(qiáng)大體現(xiàn)在“模塊自信”上,因?yàn)閜ython不僅有很強(qiáng)大的自有模塊(稱之為標(biāo)準(zhǔn)庫),還有海量的第三方模塊,任何人還都能自己開發(fā)模塊,正是有了這么強(qiáng)大的“模塊自信”,才體現(xiàn)了python的優(yōu)勢所在。并且這種方式也正在不斷被更多其它語言所借鑒。
“模塊自信”的本質(zhì)是:開放。
python不是一個封閉的體系,是一個開放系統(tǒng)。開放系統(tǒng)的最大好處就是避免了“熵增”。
熵的概念是由德國物理學(xué)家克勞修斯于1865年(這一年李鴻章建立了江南機(jī)械制造總局,美國廢除奴隸制,林肯總統(tǒng)遇刺身亡,美國南北戰(zhàn)爭結(jié)束。)所提出。是一種測量在動力學(xué)方面不能做功的能量總數(shù),也就是當(dāng)總體的熵增加,其做功能力也下降,熵的量度正是能量退化的指標(biāo)。
熵亦被用于計(jì)算一個系統(tǒng)中的失序現(xiàn)象,也就是計(jì)算該系統(tǒng)混亂的程度。
根據(jù)熵的統(tǒng)計(jì)學(xué)定義, 熱力學(xué)第二定律說明一個孤立系統(tǒng)的傾向于增加混亂程度。換句話說就是對于封閉系統(tǒng)而言,會越來越趨向于無序化。反過來,開放系統(tǒng)則能避免無序化。
在本教程的《語句(1)》中,曾經(jīng)介紹了import語句,有這樣一個例子:
>>> import math
>>> math.pow(3,2)
9.0
這里的math就是一個模塊,用import引入這個模塊,然后可以使用模塊里面的函數(shù),比如這個pow()函數(shù)。顯然,這里我們是不需要自己動手寫具體函數(shù)的,我們的任務(wù)就是拿過來使用。這就是模塊的好處:拿過來就用,不用自己重寫。
這個標(biāo)題,一語道破了模塊的本質(zhì),它就是一個擴(kuò)展名為.py
的python程序。我們能夠在應(yīng)該使用它的時候?qū)⑺眠^來,節(jié)省精力,不需要重寫雷同的代碼。
但是,如果我自己寫一個.py
文件,是不是就能作為模塊import過來呢?還不那么簡單。必須得讓python解釋器能夠找到你寫的模塊。比如:在某個目錄中,我寫了這樣一個文件:
#!/usr/bin/env python
# coding=utf-8
lang = "python"
并把它命名為pm.py,那么這個文件就可以作為一個模塊被引入。不過由于這個模塊是我自己寫的,python解釋器并不知道,我得先告訴它我寫了這樣一個文件。
>>> import sys
>>> sys.path.append("~/Documents/VBS/StartLearningPython/2code/pm.py")
用這種方式就是告訴python解釋器,我寫的那個文件在哪里。在這個告訴方法中,也用了一個模塊import sys
,不過由于sys模塊是python被安裝的時候就有的,所以不用特別告訴,python解釋器就知道它在哪里了。
上面那個一長串的地址,是ubuntu系統(tǒng)的地址格式,如果讀者使用的windows系統(tǒng),請寫你所保存的文件路徑。
>>> import pm
>>> pm.lang
'python'
本來在pm.py文件中,有一個變量lang = "python"
,這次它作為模塊引入(注意作為模塊引入的時候,不帶擴(kuò)展名),就可以通過模塊名字來訪問變量pm.py
,當(dāng)然,如果不存在的屬性這么去訪問,肯定是要報錯的。
>>> pm.xx
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'xx'
請讀者回到pm.py文件的存儲目錄,是不是多了一個擴(kuò)展名是.pyc的文件?如果不是,你那個可能是外星人用的python。
解釋器,英文是:interpreter,港臺翻譯為:直譯器。在python中,它的作用就是將.py的文件轉(zhuǎn)化為.pyc文件,而.pyc文件是由字節(jié)碼(bytecode)構(gòu)成的,然后計(jì)算機(jī)執(zhí)行.pyc文件。關(guān)于這方面的詳細(xì)解釋,請參閱維基百科的詞條:直譯器
不少人喜歡將這個世界簡化簡化再簡化。比如人,就分為好人還壞人,比如編程語言就分為解釋型和編譯型,不但如此,還將兩種類型的語言分別貼上運(yùn)行效率高低的標(biāo)簽,解釋型的運(yùn)行速度就慢,編譯型的就快。一般人都把python看成解釋型的,于是就得出它運(yùn)行速度慢的結(jié)論。不少人都因此上當(dāng)受騙了,認(rèn)為python不值得學(xué),或者做不了什么“大事”。這就是將本來復(fù)雜的多樣化的世界非得劃分為“黑白”的結(jié)果。這種喜歡用“非此即彼”的思維方式考慮問題的現(xiàn)象可以說在現(xiàn)在很常見,比如一提到“日本人”,除了蒼老師,都該殺,這基本上是小孩子的思維方法,可惜在某個過度內(nèi)大行其道。
世界是復(fù)雜的,“敵人的敵人就是朋友”是幼稚的,“一分為二”是機(jī)械的。當(dāng)然,蒼老師是德藝雙馨的。
就如同剛才看到的那個.pyc文件一樣,當(dāng)python解釋器讀取了.py文件,先將它變成由字節(jié)碼組成的.pyc文件,然后這個.pyc文件交給一個叫做python虛擬機(jī)的東西去運(yùn)行(那些號稱編譯型的語言也是這個流程,不同的是它們先有一個明顯的編譯過程,編譯好了之后再運(yùn)行)。如果.py文件修改了,python解釋器會重新編譯,只是這個編譯過程不是完全顯示給你看的。
我這里說的比較籠統(tǒng),要深入了解python程序的執(zhí)行過程,可以閱讀這篇文章:說說Python程序的執(zhí)行過程
總之,有了.pyc文件后,每次運(yùn)行,就不需要從新讓解釋器來編譯.py文件了,除非.py文件修改了。這樣,python運(yùn)行的就是那個編譯好了的.pyc文件。
是否還記得,我們在前面寫有關(guān)程序,然后執(zhí)行,常常要用到if __name__ == "__main__"
。那時我們寫的.py文件是來執(zhí)行的,這時我們同樣寫了.py文件,是作為模塊引入的。這就得深入探究一下,同樣是.py文件,它是怎么知道是被當(dāng)做程序執(zhí)行還是被當(dāng)做模塊引入?
為了便于比較,將pm.py文件進(jìn)行改造,稍微復(fù)雜點(diǎn)。
#!/usr/bin/env python
# coding=utf-8
def lang():
return "python"
if __name__ == "__main__":
print lang()
如以前做的那樣,可以用這樣的方式:
$ python pm.py
python
但是,如果將這個程序作為模塊,導(dǎo)入,會是這樣的:
>>> import sys
>>> sys.path.append("~/Documents/VBS/StarterLearningPython/2code/pm.py")
>>> import pm
>>> pm.lang()
'python'
因?yàn)檫@時候pm.py中的函數(shù)lang()就是一個屬性:
>>> dir(pm)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'lang']
同樣一個.py文件,可以把它當(dāng)做程序來執(zhí)行,還可以將它作為模塊引入。
>>> __name__
'__main__'
>>> pm.__name__
'pm'
如果要作為程序執(zhí)行,則__name__ == "__main__"
;如果作為模塊引入,則pm.__name__ == "pm"
,即變量__name__
的值是模塊名稱。
用這種方式就可以區(qū)分是執(zhí)行程序還是作為模塊引入了。
在一般情況下,如果僅僅是用作模塊引入,可以不寫if __name__ == "__main__"
。
為了讓我們自己寫的模塊能夠被python解釋器知道,需要用sys.path.append("~/Documents/VBS/StarterLearningPython/2code/pm.py")
。其實(shí),在python中,所有模塊都被加入到了sys.path里面了。用下面的方法可以看到模塊所在位置:
>>> import sys
>>> import pprint
>>> pprint.pprint(sys.path)
['',
'/usr/local/lib/python2.7/dist-packages/autopep8-1.1-py2.7.egg',
'/usr/local/lib/python2.7/dist-packages/pep8-1.5.7-py2.7.egg',
'/usr/lib/python2.7',
'/usr/lib/python2.7/plat-i386-linux-gnu',
'/usr/lib/python2.7/lib-tk',
'/usr/lib/python2.7/lib-old',
'/usr/lib/python2.7/lib-dynload',
'/usr/local/lib/python2.7/dist-packages',
'/usr/lib/python2.7/dist-packages',
'/usr/lib/python2.7/dist-packages/PILcompat',
'/usr/lib/python2.7/dist-packages/gtk-2.0',
'/usr/lib/python2.7/dist-packages/ubuntu-sso-client',
'~/Documents/VBS/StarterLearningPython/2code/pm.py']
從中也發(fā)現(xiàn)了我們自己寫的那個文件。凡在上面列表所包括位置內(nèi)的.py文件都可以作為模塊引入。不妨舉個例子。把前面自己編寫的pm.py文件修改為pmlib.py,然后把它復(fù)制到'/usr/lib/python2.7/dist-packages
中。(這是以ubuntu為例說明,如果是其它操作系統(tǒng),讀者用類似方法也能找到。)
$ sudo cp pm.py /usr/lib/python2.7/dist-packages/pmlib.py
[sudo] password for qw:
$ ls /usr/lib/python2.7/dist-packages/pm*
/usr/lib/python2.7/dist-packages/pmlib.py
文件放到了指定位置??聪旅娴模?/p>
>>> import pmlib
>>> pmlib.lang
<function lang at 0xb744372c>
>>> pmlib.lang()
'python'
也就是,要將模塊文件放到合適的位置——就是sys.path包括位置——就能夠直接用import引入了。
將模塊文件放到指定位置是一種不錯的方法。當(dāng)程序員都喜歡自由,能不能放到別處呢?當(dāng)然能,用sys.path.append()
就是不管把文件放哪里,都可以把其位置告訴python解釋器。但是,這種方法不是很常用。因?yàn)樗灿新闊┑牡胤剑热缭诮换ツJ较?,如果關(guān)閉了,然后再開啟,還得從新告知。
比較常用的告知方法是設(shè)置PYTHONPATH環(huán)境變量。
環(huán)境變量,不同操作系統(tǒng)的設(shè)置方法略有差異。讀者可以根據(jù)自己的操作系統(tǒng),到網(wǎng)上搜索設(shè)置方法。
我以ubuntu為例,建立一個python的目錄,然后將我自己寫的.py文件放到這里,并設(shè)置環(huán)境變量。
:~$ mkdir python
:~$ cd python
:~/python$ cp ~/Documents/VBS/StarterLearningPython/2code/pm.py mypm.py
:~/python$ ls
mypm.py
然后將這個目錄~/python
,也就是/home/qw/python
設(shè)置環(huán)境變量。
vim /etc/profile
提醒要用root權(quán)限,在打開的文件最后增加export PATH = /home/qw/python:$PAT
,然后保存退出即可。
注意,我是在~/python
目錄下輸入python
,進(jìn)入到交互模式:
:~$ cd python
:~/python$ python
>>> import mypm
>>> mypm.lang()
'python'
如此,就完成了告知過程。
__init__.py
方法__init__.py
是一個空文件,將它放在某個目錄中,就可以將該目錄中的其它.py文件作為模塊被引用。這個具體應(yīng)用參見用tornado做網(wǎng)站(2)
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: