分享8點(diǎn)超級(jí)有用的Python編程建議(推薦)
我們?cè)谟肞ython進(jìn)行機(jī)器學(xué)習(xí)建模項(xiàng)目的時(shí)候,每個(gè)人都會(huì)有自己的一套項(xiàng)目文件管理的習(xí)慣,我自己也有一套方法,是自己曾經(jīng)踩過(guò)的坑總結(jié)出來(lái)的,現(xiàn)在在這里分享一下給大家,希望多少有些地方可以給大家借鑒。
🚗 先睹為快
- 項(xiàng)目文件事先做好歸檔
- 永遠(yuǎn)不要手動(dòng)修改源數(shù)據(jù)并且做好備份
- 做好路徑的正確配置
- 代碼必要的地方做好備注與說(shuō)明
- 加速你的Python循環(huán)代碼
- 可視化你的循環(huán)代碼進(jìn)度
- 使用高效的異常捕獲工具
- 要多考慮代碼健壯性
項(xiàng)目文件事先做好歸檔
每次開(kāi)始一個(gè)新工作的時(shí)候,以前的我總是貪圖方便,Code、Data、文檔都集中放在一個(gè)文件夾內(nèi),看起來(lái)很亂,一度讓回溯過(guò)程十分痛苦,或者是換了部電腦,文件全都運(yùn)行不行了,需要自行修改路徑,十分痛苦。
經(jīng)過(guò)自己一番探索,大家可以大致將項(xiàng)目分成幾個(gè)子文件夾,code放在主文件夾里:
永遠(yuǎn)不要手動(dòng)修改源數(shù)據(jù)并且做好備份
我們需要對(duì)源數(shù)據(jù)進(jìn)行好備份,方便我們下一次進(jìn)行回溯,可以進(jìn)行下一步的操作或者是對(duì)中間步驟的修改,而且,對(duì)代碼等其他文件也是需要做好備份的,以免出現(xiàn)意外丟失。
這里來(lái)自良許Linux的一篇文章,推薦了4個(gè)工具:
- Git版本控制系統(tǒng)
- Rsync文件備份
- Dropbox云存儲(chǔ)
- Time Machine時(shí)光機(jī)器
更多的工具介紹和使用我這邊就不展開(kāi),大家可以去自行了解唄。
做好路徑的正確配置
很多同學(xué)在寫(xiě)路徑的時(shí)候都很喜歡直接用絕對(duì)路徑,雖然一般情況下不會(huì)有什么問(wèn)題,但如果代碼共享給其他人學(xué)習(xí)或者運(yùn)行的時(shí)候,問(wèn)題就來(lái)了,很多情況下都不能直接跑通,
這里建議:
- 使用相對(duì)路徑:腳本位于主目錄下,其他資源(如數(shù)據(jù)、第三方包等)在其同級(jí)或低級(jí)目錄下,如 ./data/processed/test1.csv
- 全局路徑配置變量:
# 設(shè)置主目錄 HOME_PATH = r'E:\ML\190615- PROJECT1' # 讀取數(shù)據(jù) data = open(HOME_PATH+'/data/processed/test1.csv') data = pd.read_csv(data) data.head()
代碼必要的地方做好備注與說(shuō)明
這個(gè)我相信大多數(shù)人都感同身受了,不信?拿回一個(gè)月前自己寫(xiě)的代碼看看吧,看一下能看懂多少(如果沒(méi)有做好備注說(shuō)明的話)
加速你的Python循環(huán)代碼
這里推薦云哥的一篇文章:24式加速你的python:
http://chabaoo.cn/article/162967.htm
收藏起來(lái),多看多幾次,養(yǎng)成好習(xí)慣唄,這樣子你寫(xiě)代碼才會(huì)越來(lái)越快~
可視化你的循環(huán)代碼進(jìn)度
這里介紹一個(gè)Python庫(kù),tqdm,先安裝一下:pip install tqdm
這個(gè)是一個(gè)可以顯示循環(huán)進(jìn)度的庫(kù),有了它就可以更加運(yùn)籌帷幄了。
大家可以看下面的例子:
使用高效的異常捕獲工具
異常bug定位,以前的我經(jīng)常也是一條print()函數(shù)走到底,雖然說(shuō)也沒(méi)什么問(wèn)題,但效率上還是會(huì)比較慢,后來(lái)發(fā)現(xiàn)了一個(gè)叫PySnooper的裝飾器,仿佛發(fā)現(xiàn)了新大陸。
我們一般debug,都是在我們可能覺(jué)得會(huì)有問(wèn)題的地方,去打印輸出,看下實(shí)際輸出了什么,然后思考問(wèn)題所在,這需要我們?nèi)ジ腸ode,非常細(xì)致地改,相比較直接加個(gè)裝飾器,是十分麻煩的。
大家可以看看Example:
import pysnooper @pysnooper.snoop('./log/file.log') def number_to_bits(number): if number: bits = [] while number: number, remainder = divmod(number, 2) bits.insert(0, remainder) return bits else: return [0] number_to_bits(6)
我們把函數(shù)每一步的輸出都保存為file.log,我們可以直接去看到底哪里出了問(wèn)題。
📚 項(xiàng)目地址:https://github.com/cool-RR/pysnooper
要多考慮代碼健壯性
何為代碼的健壯性,顧名思義,就是可以抵擋得住各種異常場(chǎng)景的測(cè)試,異常處理工作由“捕獲”和“拋出”兩部分組成?!安东@”指的是使用 try ... except 包裹特定語(yǔ)句,妥當(dāng)?shù)耐瓿慑e(cuò)誤流程處理。而恰當(dāng)?shù)氖褂?raise 主動(dòng)“拋出”異常,更是優(yōu)雅代碼里必不可少的組成部分,下面總結(jié)幾點(diǎn)供大家參考:
1)知道要傳入的參數(shù)是什么,類型,個(gè)數(shù)....(異常處理,邏輯判斷)
def add(a, b): if isinstance(a, int) and isinstance(b, int): return a+b else: return '參數(shù)類型錯(cuò)誤' print(add(1, 2)) print(add(1, 'a'))
2)只做最精準(zhǔn)的異常捕獲
我們有的時(shí)候想著讓腳本work才是王道,所以不管三七二十一就搞一個(gè)大大的try...except把整塊代碼包裹起來(lái),但這樣很容易把原本該被拋出的 AttibuteError 吞噬了。從而給我們的 debug 過(guò)程增加了不必要的麻煩。
所以,我們永遠(yuǎn)只捕獲那些可能會(huì)拋出異常的語(yǔ)句塊,而且盡量只捕獲精確的異常類型,而不是模糊的 Exception。
from requests.exceptions import RequestException def save_website_title(url, filename): try: resp = requests.get(url) except RequestException as e: print(f'save failed: unable to get page content: {e}') return False # 這段正則操作本身就是不應(yīng)該拋出異常的,所以我們沒(méi)必要使用 try 語(yǔ)句塊 # 假如 group 被誤打成了 grop 也沒(méi)關(guān)系,程序馬上就會(huì)通過(guò) AttributeError 來(lái) # 告訴我們。 obj = re.search(r'<title>(.*)</title>', resp.text) if not obj: print('save failed: title tag not found in page content') return False title = obj.group(1) try: with open(filename, 'w') as fp: fp.write(title) except IOError as e: print(f'save failed: unable to write to file {filename}: {e}') return False else: return True
3)異常處理不應(yīng)該喧賓奪主
像上一條說(shuō)到的異常捕獲要精準(zhǔn),但如果每一個(gè)都很精準(zhǔn)的話,其實(shí)我們的代碼里就會(huì)有很多try...except語(yǔ)句塊,以至于擾亂核心代碼,代碼整體閱讀性。
這里,我們可以利用上下文管理器來(lái)改善我們的異常處理流程,簡(jiǎn)化重復(fù)的異常處理邏輯。
class raise_api_error: """captures specified exception and raise ApiErrorCode instead :raises: AttributeError if code_name is not valid """ def __init__(self, captures, code_name): self.captures = captures self.code = getattr(error_codes, code_name) def __enter__(self): # 該方法將在進(jìn)入上下文時(shí)調(diào)用 return self def __exit__(self, exc_type, exc_val, exc_tb): # 該方法將在退出上下文時(shí)調(diào)用 # exc_type, exc_val, exc_tb 分別表示該上下文內(nèi)拋出的 # 異常類型、異常值、錯(cuò)誤棧 if exc_type is None: return False if exc_type == self.captures: raise self.code from exc_val return False
在上面的代碼里,我們定義了一個(gè)名為 raise_api_error 的上下文管理器,它在進(jìn)入上下文時(shí)什么也不做。但是在退出上下文時(shí),會(huì)判斷當(dāng)前上下文中是否拋出了類型為 self.captures 的異常,如果有,就用 APIErrorCode 異常類替代它。
使用上下文管理器后,簡(jiǎn)潔的代碼如下:
def upload_avatar(request): """用戶上傳新頭像""" with raise_api_error(KeyError, 'AVATAR_FILE_NOT_PROVIDED'): avatar_file = request.FILES['avatar'] with raise_api_error(ResizeAvatarError, 'AVATAR_FILE_INVALID'),\ raise_api_error(FileTooLargeError, 'AVATAR_FILE_TOO_LARGE'): resized_avatar_file = resize_avatar(avatar_file) with raise_api_error(Exception, 'INTERNAL_SERVER_ERROR'): request.user.avatar = resized_avatar_file request.user.save() return HttpResponse({})
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
python中根據(jù)字符串調(diào)用函數(shù)的實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇python中根據(jù)字符串調(diào)用函數(shù)的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧2016-06-06Python實(shí)現(xiàn)的ftp服務(wù)器功能詳解【附源碼下載】
這篇文章主要介紹了Python實(shí)現(xiàn)的ftp服務(wù)器功能,結(jié)合實(shí)例形式分析了Python構(gòu)建ftp服務(wù)器功能的相關(guān)設(shè)置、實(shí)現(xiàn)技巧與操作注意事項(xiàng),并附帶源碼供讀者下載參考,需要的朋友可以參考下2019-06-06詳解Django框架中用context來(lái)解析模板的方法
這篇文章主要介紹了詳解Django框架中用context來(lái)解析模板的方法,Django是重多高人氣Python框架中最為著名的一個(gè),需要的朋友可以參考下2015-07-07python中Flask框架簡(jiǎn)單入門(mén)實(shí)例
這篇文章主要介紹了python中Flask框架簡(jiǎn)單入門(mén)實(shí)例,以一個(gè)hello程序簡(jiǎn)單分析了Flask框架的使用技巧,需要的朋友可以參考下2015-03-03Python 爬蟲(chóng)之超鏈接 url中含有中文出錯(cuò)及解決辦法
這篇文章主要介紹了Python 爬蟲(chóng)之超鏈接 url中含有中文出錯(cuò)及解決辦法的相關(guān)資料,出現(xiàn)UnicodeEncodeError: 'ascii' codec can't encode characters,的錯(cuò)誤解決辦法,需要的朋友可以參考下2017-08-08Python進(jìn)程池log死鎖問(wèn)題分析及解決
最近線上運(yùn)行的一個(gè)python任務(wù)負(fù)責(zé)處理一批數(shù)據(jù),為提高處理效率,使用了python進(jìn)程池,并會(huì)打印log,本文給大家分析了Python進(jìn)程池log死鎖問(wèn)題以及解決方法,需要的朋友可以參考下2024-01-01Python高級(jí)編程之消息隊(duì)列(Queue)與進(jìn)程池(Pool)實(shí)例詳解
這篇文章主要介紹了Python高級(jí)編程之消息隊(duì)列(Queue)與進(jìn)程池(Pool),結(jié)合實(shí)例形式詳細(xì)分析了Python消息隊(duì)列與進(jìn)程池的相關(guān)原理、使用技巧與操作注意事項(xiàng),需要的朋友可以參考下2019-11-11Python實(shí)現(xiàn)電腦壁紙的采集與輪換效果
這篇文章主要為大家介紹了如何利用Python實(shí)現(xiàn)電腦壁紙的采集以及輪換效果,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Python有一定幫助,需要的可以參考一下2022-04-04