第二章 共享你的Python代碼

上一章結(jié)尾我們講到用函數(shù)來封裝代碼以便于復(fù)用。但是你有沒有發(fā)現(xiàn)我們寫的代碼在IDLE里靶溜,無法保存下來匾乓,如果我們進行真正開發(fā)工作,而且肯定會和其他人合作開發(fā) 鳄厌,都將代碼寫在IDLE里是不行的荞胡。所以我們現(xiàn)在需要解決兩個問題:

  • 使用真正的IDE
  • 將代碼放在多個文件中

Python的編輯器選擇

用什么IDE開發(fā)Python這個真不好說,看個人喜好了嚎、公司規(guī)范都行硝训。比如Windows下的同學(xué)可以使用NotePad++,Mac可以使用Sublime Text新思。我在這里建議大家可以試試Visual Studio Code窖梁,它是微軟推出的輕量級、跨平臺IDE夹囚,這款I(lǐng)DE有很好的Python支持纵刘,智能提示、語法檢測荸哟、調(diào)試等假哎。而且有很多實用的插件供大家使用。

這里附上下載地址:http://code.visualstudio.com/Download


安裝IDE中...

將Python代碼模塊化

已經(jīng)準(zhǔn)備好了開發(fā)工具鞍历,那么就繼續(xù)開始學(xué)習(xí)了舵抹。首先我們把上一篇的代碼再寫一遍,這次使用IDE來編寫劣砍,然后文件保存為list_loop.py惧蛹。代碼如下:

def loop(list_item):
    for item in list_item:
        if isinstance(item, list):
            loop(item)
        else:
            print(item)      

然后在目錄下找到這個文件,使用右鍵-打開方式用IDLE打開這個list_loop.py。這時候你應(yīng)該會看到剛才寫的函數(shù)代碼香嗓。按F5執(zhí)行迅腔,會出現(xiàn)一個新的命令界面,這時候我們創(chuàng)建一個列表靠娱,然后調(diào)用剛才的函數(shù)沧烈。

>>> books = [['機械工業(yè)出版社',['C++入門', 50.9],['Java編程思想', 60.5]],
         ['人民郵電出版社',['Android開發(fā)詳解', 76.5],['HTML5技術(shù)探索', 78.9]],
         ['中國電力出版社' ,['iOS設(shè)計模式', 88.3]]]
>>> loop(books)
機械工業(yè)出版社
C++入門
50.9
Java編程思想
60.5
人民郵電出版社
Android開發(fā)詳解
76.5
HTML5技術(shù)探索
78.9
中國電力出版社
iOS設(shè)計模式
88.3
>>> 

在使用函數(shù)的時候,你可以試試用TAB像云,IDLE會有相應(yīng)的代碼提示锌雀。這樣我們就成功的引用外部函數(shù)了。


Pyhton代碼中引用其它模塊

但是我們的列表不是在py文件中創(chuàng)建的迅诬,我們再來改造一下代碼汤锨,將列表數(shù)據(jù)也單獨寫到一個文件中。在list_loop.py同級目錄新建一個文件test_list_loop.py百框,內(nèi)容如下:

import list_loop

books = [['機械工業(yè)出版社',['C++入門', 50.9],['Java編程思想', 60.5]],
         ['人民郵電出版社',['Android開發(fā)詳解', 76.5],['HTML5技術(shù)探索', 78.9]],
         ['中國電力出版社' ,['iOS設(shè)計模式', 88.3]]]

print(loop(books))

可以看到首行有一句話imoprt list_loop 它的含義是將list_loop.py模塊引入我們當(dāng)前的代碼中。現(xiàn)在我們用IDLE打開test_list_loop.py文件牍汹,還是按F5來執(zhí)行铐维。不出意外,你應(yīng)該得到一個錯誤提示:

Traceback (most recent call last):
  File "/test_list_loop.py", line 7, in <module>
    print(loop(books))
NameError: name 'loop' is not defined
>>> 

提示說loop沒有定義慎菲,這是為什么呢嫁蛇?其實很好理解,我們在第一行告訴IDLE導(dǎo)入了list_loop模塊露该,而list_loop是一個命名空間睬棚,命名空間就像是一個地區(qū)名稱,比如你想找小明解幼,1班有個小明抑党,2班也有個小明,你需要給出完整的地址才可以幫你找到撵摆。也就是說你想用loop這個方法底靠,你需要告訴IDEloop具體是哪個命名空間里的函數(shù)才可以,于是我們可以這么改:

print(list_loop.loop(books))

將loop函數(shù)前面加上命名空間特铝,這樣就可以成功的運行了暑中。Python的所有代碼都與一個命名空間關(guān)聯(lián)。我們使用的BIF都是在一個名字為__main__的命名空間中鲫剿,所以我們才可以便捷的使用這些函數(shù)鳄逾。
還有一種方式也可以解決這個問題:

from list_loop import loop
#省略代碼...
print(loop(books))

使用from list_loop import loop來指定引用的函數(shù),這樣一來就不必再使用命名空間來調(diào)用函數(shù)了灵莲。不過這樣也會帶來一個問題雕凹,如果你當(dāng)前的命名空間中已經(jīng)定義了相同的函數(shù)名稱,它將會被import進來的函數(shù)所覆蓋,所以盡量使用完成的命名空間來處理這些函數(shù)一個不錯的習(xí)慣请琳。


總結(jié)

今天我們學(xué)習(xí)了:

  • 使用更加強壯的開發(fā)工具來寫Python粱挡。
  • 將Python代碼放在不同文件中。
  • 使用import <modules>導(dǎo)入其它模塊俄精。

本章總的來說內(nèi)容還是很輕松的询筏,如果大家喜歡請點贊、收藏竖慧,我會繼續(xù)更新后面的章節(jié)嫌套。
上一章結(jié)尾我們講到用函數(shù)來封裝代碼以便于復(fù)用。但是你有沒有發(fā)現(xiàn)我們寫的代碼在IDLE里圾旨,無法保存下來踱讨,如果我們進行真正開發(fā)工作,而且肯定會和其他人合作開發(fā) 砍的,都將代碼寫在IDLE里是不行的痹筛。所以我們現(xiàn)在需要解決兩個問題:

  • 使用真正的IDE
  • 將代碼放在多個文件中

Python的編輯器選擇

用什么IDE開發(fā)Python這個真不好說,看個人喜好廓鞠、公司規(guī)范都行帚稠。比如Windows下的同學(xué)可以使用NotePad++,Mac可以使用Sublime Text床佳。我在這里建議大家可以試試Visual Studio Code滋早,它是微軟推出的輕量級、跨平臺IDE砌们,這款I(lǐng)DE有很好的Python支持杆麸,智能提示、語法檢測浪感、調(diào)試等昔头。而且有很多實用的插件供大家使用。

這里附上下載地址:http://code.visualstudio.com/Download


安裝IDE中...

將Python代碼模塊化

已經(jīng)準(zhǔn)備好了開發(fā)工具影兽,那么就繼續(xù)開始學(xué)習(xí)了减细。首先我們把上一篇的代碼再寫一遍,這次使用IDE來編寫赢笨,然后文件保存為list_loop.py未蝌。代碼如下:

def loop(list_item):
    for item in list_item:
        if isinstance(item, list):
            loop(item)
        else:
            print(item)      

然后在目錄下找到這個文件,使用右鍵-打開方式用IDLE打開這個list_loop.py茧妒。這時候你應(yīng)該會看到剛才寫的函數(shù)代碼萧吠。按F5執(zhí)行,會出現(xiàn)一個新的命令界面桐筏,這時候我們創(chuàng)建一個列表纸型,然后調(diào)用剛才的函數(shù)。

>>> books = [['機械工業(yè)出版社',['C++入門', 50.9],['Java編程思想', 60.5]],
         ['人民郵電出版社',['Android開發(fā)詳解', 76.5],['HTML5技術(shù)探索', 78.9]],
         ['中國電力出版社' ,['iOS設(shè)計模式', 88.3]]]
>>> loop(books)
機械工業(yè)出版社
C++入門
50.9
Java編程思想
60.5
人民郵電出版社
Android開發(fā)詳解
76.5
HTML5技術(shù)探索
78.9
中國電力出版社
iOS設(shè)計模式
88.3
>>> 

在使用函數(shù)的時候,你可以試試用TAB狰腌,IDLE會有相應(yīng)的代碼提示除破。這樣我們就成功的引用外部函數(shù)了。


Pyhton代碼中引用其它模塊

但是我們的列表不是在py文件中創(chuàng)建的琼腔,我們再來改造一下代碼瑰枫,將列表數(shù)據(jù)也單獨寫到一個文件中。在list_loop.py同級目錄新建一個文件test_list_loop.py丹莲,內(nèi)容如下:

import list_loop

books = [['機械工業(yè)出版社',['C++入門', 50.9],['Java編程思想', 60.5]],
         ['人民郵電出版社',['Android開發(fā)詳解', 76.5],['HTML5技術(shù)探索', 78.9]],
         ['中國電力出版社' ,['iOS設(shè)計模式', 88.3]]]

print(loop(books))

可以看到首行有一句話imoprt list_loop 它的含義是將list_loop.py模塊引入我們當(dāng)前的代碼中」獍樱現(xiàn)在我們用IDLE打開test_list_loop.py文件,還是按F5來執(zhí)行甥材。不出意外盯另,你應(yīng)該得到一個錯誤提示:

Traceback (most recent call last):
  File "/test_list_loop.py", line 7, in <module>
    print(loop(books))
NameError: name 'loop' is not defined
>>> 

提示說loop沒有定義,這是為什么呢洲赵?其實很好理解鸳惯,我們在第一行告訴IDLE導(dǎo)入了list_loop模塊,而list_loop是一個命名空間叠萍,命名空間就像是一個地區(qū)名稱芝发,比如你想找小明,1班有個小明俭令,2班也有個小明,你需要給出完整的地址才可以幫你找到部宿。也就是說你想用loop這個方法抄腔,你需要告訴IDEloop具體是哪個命名空間里的函數(shù)才可以,于是我們可以這么改:

print(list_loop.loop(books))

將loop函數(shù)前面加上命名空間理张,這樣就可以成功的運行了赫蛇。Python的所有代碼都與一個命名空間關(guān)聯(lián)。我們使用的BIF都是在一個名字為__main__的命名空間中雾叭,所以我們才可以便捷的使用這些函數(shù)悟耘。
還有一種方式也可以解決這個問題:

from list_loop import loop
#省略代碼...
print(loop(books))

使用from list_loop import loop來指定引用的函數(shù),這樣一來就不必再使用命名空間來調(diào)用函數(shù)了织狐。不過這樣也會帶來一個問題暂幼,如果你當(dāng)前的命名空間中已經(jīng)定義了相同的函數(shù)名稱,它將會被import進來的函數(shù)所覆蓋移迫,所以盡量使用完成的命名空間來處理這些函數(shù)一個不錯的習(xí)慣旺嬉。


合理升級你的模塊代碼

在真正的開發(fā)中,需求變更是常有的〕瘢現(xiàn)在我們就有一個新的需求邪媳,之前的數(shù)據(jù)輸出都是一行一個排版很不好看,現(xiàn)在想做一些UI的美化,這里我們簡單設(shè)計下雨效,在出版社內(nèi)的書籍價格多加一個\t,這是最后效果:

        機械工業(yè)出版社
            C++入門
            50.9
            Java編程思想
            60.5
        人民郵電出版社
            Android開發(fā)詳解
            76.5
            HTML5技術(shù)探索
            78.9
        中國電力出版社
            iOS設(shè)計模式
            88.3

接來下開始改造loop()這個方法,增加一個索引標(biāo)記:

def loop(list_item,item_tab):
    for item in list_item:
        if isinstance(item, list):
            loop(item,item_tab+1)
        else:
            for tab in range(item_tab):
                print('\t',end='')
            print(item)

這里用到了新的BIFrange()迅涮,請自行help(range)查閱文檔。每次到if的時候item_tab+1保證內(nèi)部的列表比外部多一個tab,然后在else內(nèi)進行循環(huán)打印print('\t',end=''),這是print其它參數(shù)重載形式徽龟,可以很方便的控制打印規(guī)則叮姑,有不清楚的可以使用help(print)來查看文檔。

現(xiàn)在開始嘗試運行test_list_loop.py這個文件顿肺,還是右鍵-IDLE打開戏溺,然后F5執(zhí)行,如果你按照我說的來做的話屠尊,就會發(fā)現(xiàn)又出現(xiàn)錯誤了:

Traceback (most recent call last):
  File "/test_list_loop.py", line 7, in <module>
    print(loop(books))
TypeError: loop() missing 1 required positional argument: 'item_tab'
>>> 

TypeError提示說缺少一個參數(shù)旷祸,原來是剛才修改loop()函數(shù)忘記改調(diào)用的地方了,那我們就再改下調(diào)用的文件:

print(loop(books, 0))

雖然解決了問題讼昆,但是我們也是費了不少勁托享,不但要改公用的模塊,還需改調(diào)用的代碼浸赫,顯然這種牽一發(fā)動全身的編碼方式我們是不能接受的闰围。為了避免這種事情再次發(fā)生,我們要想出一種兼容方式來處理既峡,就是不在改調(diào)用方的情況下羡榴,合理的升級我們的公用模塊代碼。

腦洞開啟中...

我們重新寫一個函數(shù)运敢,讓舊函數(shù)調(diào)用新函數(shù)校仑,這樣就可以對調(diào)用方隱藏:

def loop(list_item):
    loop2(list_item,1)

這是一個好辦法,對調(diào)用方來說不用修改任何地方就能完成升級代碼了传惠。但是我們模塊方會因此而增加維護開銷迄沫,如果以后有新人加入,他會很困惑究竟用哪個函數(shù)卦方。顯然這種方式只能對一部分人帶來好處羊瘩。
在一番研究下,發(fā)現(xiàn)Python有個神奇的功能盼砍,剛好可以解決我們的問題尘吗,函數(shù)的入?yún)⒖梢蕴峁┠J值,而且調(diào)用方可以不用填寫有默認值的參數(shù):

def loop(list_item,item_tab=1):

調(diào)用方:

print(loop(books))

F5執(zhí)行可以順利的打印出來了浇坐,真是喜大普奔摇予。這樣就完美解決了不管是模塊維護還是業(yè)務(wù)調(diào)用,都可以用很低的成本來完成這個重大的改變吗跋。有時候多了解一些事情侧戴,就能有意想不到的收獲宁昭。


總結(jié)

今天我們學(xué)習(xí)了:

  • 使用更加強壯的開發(fā)工具來寫Python。
  • 將Python代碼放在不同文件中酗宋。
  • 使用import <modules>導(dǎo)入其它模塊积仗。
  • 新學(xué)了一個BIF:rang(),還學(xué)習(xí)了print的其它重載方式蜕猫。
  • 使用巧妙的方式來解決公用模塊的修改而不影響其他調(diào)用者寂曹。

本章總的來說內(nèi)容還是很輕松的,如果大家喜歡請點贊回右、收藏隆圆,我會繼續(xù)更新后面的章節(jié)。


恭喜你達成<Python共享者>成就翔烁。


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末渺氧,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蹬屹,更是在濱河造成了極大的恐慌侣背,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件慨默,死亡現(xiàn)場離奇詭異贩耐,居然都是意外死亡,警方通過查閱死者的電腦和手機厦取,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門潮太,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人虾攻,你說我怎么就攤上這事铡买。” “怎么了台谢?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵寻狂,是天一觀的道長岁经。 經(jīng)常有香客問我朋沮,道長,這世上最難降的妖魔是什么缀壤? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任樊拓,我火速辦了婚禮,結(jié)果婚禮上塘慕,老公的妹妹穿的比我還像新娘筋夏。我一直安慰自己,他們只是感情好图呢,可當(dāng)我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布条篷。 她就那樣靜靜地躺著骗随,像睡著了一般。 火紅的嫁衣襯著肌膚如雪赴叹。 梳的紋絲不亂的頭發(fā)上鸿染,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天,我揣著相機與錄音乞巧,去河邊找鬼涨椒。 笑死,一個胖子當(dāng)著我的面吹牛绽媒,可吹牛的內(nèi)容都是我干的蚕冬。 我是一名探鬼主播,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼是辕,長吁一口氣:“原來是場噩夢啊……” “哼囤热!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起免糕,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤赢乓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后石窑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體牌芋,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年松逊,在試婚紗的時候發(fā)現(xiàn)自己被綠了躺屁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡经宏,死狀恐怖犀暑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情烁兰,我是刑警寧澤耐亏,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站沪斟,受9級特大地震影響广辰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜主之,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一择吊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧槽奕,春花似錦几睛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽囱持。三九已至,卻和暖如春焕济,著一層夾襖步出監(jiān)牢的瞬間洪唐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工吼蚁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留凭需,地道東北人。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓肝匆,卻偏偏與公主長得像粒蜈,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子旗国,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容

  • http://python.jobbole.com/85231/ 關(guān)于專業(yè)技能寫完項目接著寫寫一名3年工作經(jīng)驗的J...
    燕京博士閱讀 7,575評論 1 118
  • 前言 ||| 第二章 使用ArcPy編寫腳本 Python支持大部分在其他語言中出現(xiàn)的編程結(jié)構(gòu)漩蟆。在本章內(nèi)容中蜗侈,我們...
    muyan閱讀 90,037評論 10 55
  • 22年12月更新:個人網(wǎng)站關(guān)停,如果仍舊對舊教程有興趣參考 Github 的markdown內(nèi)容[https://...
    tangyefei閱讀 35,181評論 22 257
  • 個人筆記,方便自己查閱使用 Py.LangSpec.Contents Refs Built-in Closure ...
    freenik閱讀 67,698評論 0 5
  • 不是所有的花都能開在冬天 不是所有的石頭都能遇到米開朗基羅 不是所有的人趁冈,都會邂逅你的容顏 不是所有的月光都能照亮...
    張權(quán)偉閱讀 203評論 0 1