高質(zhì)量Python代碼編寫(xiě)的5個(gè)優(yōu)化技巧
如今我使用 Python 已經(jīng)很長(zhǎng)時(shí)間了,但當(dāng)我回顧之前寫(xiě)的一些代碼時(shí),有時(shí)候會(huì)感到很沮喪。例如,最早使用 Python 時(shí),我寫(xiě)了一個(gè)名為 Sudoku 的游戲(GitHub地址:https://github.com/MichaelWashburnJr/PythonSudoku)。這個(gè)游戲在當(dāng)時(shí)算是我比較拿得出手的項(xiàng)目了。然而現(xiàn)在,我無(wú)法直接復(fù)制其代碼并運(yùn)行它,具體原因是我當(dāng)時(shí)編碼時(shí)沒(méi)有添加一個(gè)setup.py 或者 requires.txt 文件,當(dāng)然,這種錯(cuò)誤我肯定不會(huì)再犯!
由此,我總結(jié)了多年來(lái)自己所編寫(xiě)的 Python 代碼的質(zhì)量變化過(guò)程。它們變得更加簡(jiǎn)潔、健壯、易讀。但是什么原因使得 Python 代碼變得更好呢?
在本文中筆者將與大家共同探討一些 Python 代碼的優(yōu)化手段,或大或小。希望以此幫助你提高 Python 代碼的質(zhì)量。當(dāng)然,這些方式也可以適用于其他編程語(yǔ)言和技術(shù)。
1. 將代碼設(shè)置為可通過(guò) PIP 安裝的軟件包
當(dāng)你想要使用一個(gè)新的 Python 包時(shí),如果可以使用 “pip install”命令跟上包名或者包的位置來(lái)安裝的話(huà),就會(huì)非常方便。
有很多方法可以實(shí)現(xiàn)這一點(diǎn),我的“go to”項(xiàng)目實(shí)現(xiàn)方法是創(chuàng)建一個(gè) setup.py 文件。
假設(shè)我們?cè)凇癴lask_example.py”中有一個(gè)簡(jiǎn)單的 Flask 程序:
from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello, World!' def main(): app.run() if __name__ == ‘__main__': main()
我們可以將其設(shè)置為一個(gè)可安裝的 Python 包。方法是:首先把它移動(dòng)到一個(gè)單獨(dú)的文件夾中(我們稱(chēng)之為“flask_example /”),然后在項(xiàng)目根文件夾中創(chuàng)建一個(gè)如下所示的setup.py 文件:
from distutils.core import setup setup( name='flask_example', version='1.0', description='Hello, World! in flask.', packages=['flask_example'], install_requires=[ 'Flask==0.12.2' ], entry_points = { 'console_scripts': 'runserver=flask_example.flask_example:main' } )
這樣做可以帶來(lái)一系列優(yōu)點(diǎn)。 首先,你可以使用“pip install -e”在本地安裝你的應(yīng)用程序。這樣,開(kāi)發(fā)人員可以輕松克隆和安裝項(xiàng)目,因?yàn)?setup.py 文件將會(huì)處理掉所有繁重的工作。
其次,使用 setup.py 文件來(lái)進(jìn)行依賴(lài)關(guān)系管理。install_requires 變量能夠定義要使用的軟件包以及版本。如果你不確定使用的軟件包名稱(chēng)和版本,可以運(yùn)行“pip freeze”來(lái)查看它們。
最后,它可以為你的程序包定義入口點(diǎn),通過(guò)簡(jiǎn)單運(yùn)行“runserver”即可在命令行中執(zhí)行代碼。
2. 借助 linter 工具捕獲代碼錯(cuò)誤
使用 linter(語(yǔ)法檢查)可以自動(dòng)修復(fù)代碼的語(yǔ)法問(wèn)題。PyLint 是一款強(qiáng)大的 Python 版本的 linter 工具,如果你使用類(lèi)似 Git 這樣的版本控制系統(tǒng),可以在提交代碼之前讓 Git 通過(guò)一個(gè) linter 運(yùn)行代碼來(lái)解決語(yǔ)法問(wèn)題。
首先需要安裝 PyLint 軟件包:
pip install pylint
然后,將以下代碼添加到.git/hooks/pre-commit。如果你已經(jīng)有一個(gè) pre-commit hook,那么只需將 pylint 命令附加到文件的末尾即可。
#!/bin/sh pylint <your_package_name>
這樣做之后就可以在代碼提交到 Git 存儲(chǔ)庫(kù)之前自動(dòng)捕獲各種錯(cuò)誤。除了語(yǔ)法錯(cuò)誤之外,它還能捕捉一些其他的 linter 工具能夠捕捉到的常見(jiàn)錯(cuò)誤。
3. 盡量使用絕對(duì)路徑導(dǎo)入而不是相對(duì)路徑
在 Python 中,使用相對(duì)路徑導(dǎo)入模塊的情況很少(例如 from . import <模塊名>)。如果你已經(jīng)為 Python 項(xiàng)目創(chuàng)建一個(gè) setup.py(或者使用其他類(lèi)似的機(jī)制)文件,那么你可以簡(jiǎn)單地通過(guò)模塊的完整路徑引用其子模塊。
PEP-8(Python風(fēng)格指南) 推崇絕對(duì)路徑導(dǎo)入。這樣的話(huà)包名更加直觀,根據(jù) Python 軟件基金會(huì)的說(shuō)法就是“更規(guī)范”。
使用相對(duì)路徑的做法很快就會(huì)變成一場(chǎng)噩夢(mèng)。早期的時(shí)候可能沒(méi)有問(wèn)題,但是一旦你改名了模塊路徑或者進(jìn)行重大的重構(gòu)之后,它真的會(huì)讓你很頭痛。
4. 上下文管理(with 關(guān)鍵字)
無(wú)論何時(shí)打開(kāi)文件、流或者連接,你通常都會(huì)使用上下文管理器。上下文管理器很有用,它能夠處理文件的關(guān)閉并拋出異常。Python 中使用 with 關(guān)鍵字可以很好的實(shí)現(xiàn)該功能。
大多數(shù) Python 初學(xué)者可能會(huì)使用如下方式寫(xiě)入文件:
f = open(‘newfile.txt', ‘w') f.write(‘Hello, World!') f.close()
這樣做很簡(jiǎn)單,但是想象一下這種情況:假設(shè)你在文件中寫(xiě)入了數(shù)千行,不幸的是突然拋出異常,你的文件并未正確關(guān)閉,此時(shí)你已經(jīng)寫(xiě)入文件的所有數(shù)據(jù)都會(huì)損壞或者丟失。
不用擔(dān)心,通過(guò)一些簡(jiǎn)單的重構(gòu),即使遇到異常我們也可以確保文件正常關(guān)閉。我們可以這樣做:
with open(‘file', ‘w') as file: file.write(‘Hello, World!')
非常簡(jiǎn)單!并且代碼變得更加簡(jiǎn)潔。你還可以使用單個(gè)“with”語(yǔ)句打開(kāi)多個(gè)上下文管理器,而無(wú)需嵌套多個(gè)“with”語(yǔ)句。
with open(‘file1', ‘w') as f1, open(‘file2', ‘w') as f2: f1.write(‘Hello') f2.write(‘World')
5. 使用直觀、貼切的函數(shù)和變量名
在 Python 中,很容易對(duì)函數(shù)和返回值產(chǎn)生疑惑。特別是當(dāng)你調(diào)用某些庫(kù)里的函數(shù)時(shí)。如果你能夠避免開(kāi)發(fā)者通過(guò)查詢(xún)文檔才能得知函數(shù)功能,這樣的時(shí)間節(jié)省將是一個(gè)非常有價(jià)值的改進(jìn)。如何做到呢?如何改變一些簡(jiǎn)單的變量名稱(chēng)來(lái)節(jié)省開(kāi)發(fā)時(shí)間呢?
在命名函數(shù)或變量名時(shí),我會(huì)著重考慮3點(diǎn):
- 函數(shù)或變量的功能
- 與函數(shù)或變量相關(guān)聯(lián)的單位
- 函數(shù)或變量計(jì)算的數(shù)據(jù)類(lèi)型
例如,如果我想創(chuàng)建一個(gè)函數(shù)來(lái)計(jì)算一個(gè)矩形的面積,我將函數(shù)命名為“calc_rect_area”。但這并沒(méi)有給用戶(hù)提供足夠的信息。函數(shù)會(huì)返回值嗎?還是將值存儲(chǔ)在其他某個(gè)地方?返回值的單位是英尺還是米呢?
為了使函數(shù)名提供更多信息,我將其修改為“get_rect_area_sq_ft”。這使得用戶(hù)清楚地知道該函數(shù)獲取并返回面積,并且單位是英尺。
如果你使用一些更加友好的函數(shù)和變量名為開(kāi)發(fā)人員節(jié)省5分鐘,這些時(shí)間累積起來(lái)將大大提升開(kāi)發(fā)者的效率。
總結(jié)
這些方法是我多年使用 Python 編程所積累的經(jīng)驗(yàn)。有些是我自己的總結(jié),有些來(lái)自他人的指點(diǎn)。我希望上述建議能夠助你寫(xiě)出更好的 Python 代碼。
作者丨Michael Washburn Jr.
譯者丨安翔
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python使用django解決跨域請(qǐng)求的問(wèn)題
這篇文章主要給大家介紹了python如何使用django解決跨域請(qǐng)求的問(wèn)題,文中有詳細(xì)的代碼示例,具有一定的參考價(jià)值,需要的朋友可以參考下2023-07-07python多進(jìn)程中的生產(chǎn)者和消費(fèi)者模型詳解
這篇文章主要介紹了python多進(jìn)程中的生產(chǎn)者和消費(fèi)者模型,生產(chǎn)者是指生產(chǎn)數(shù)據(jù)的任務(wù),消費(fèi)者是指消費(fèi)數(shù)據(jù)的任務(wù)。當(dāng)生產(chǎn)者的生產(chǎn)能力遠(yuǎn)大于消費(fèi)者的消費(fèi)能力,生產(chǎn)者就需要等消費(fèi)者消費(fèi)完才能繼續(xù)生產(chǎn)新的數(shù)據(jù)2023-03-03Python人工智能深度學(xué)習(xí)RNN模型結(jié)構(gòu)流程
這篇文章主要為大家介紹了Python人工智能深度學(xué)習(xí)RNN的模型流程結(jié)構(gòu),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-11-11Python Pandas分組聚合的實(shí)現(xiàn)方法
這篇文章主要介紹了Python Pandas分組聚合的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07Python3實(shí)現(xiàn)的畫(huà)圖及加載圖片動(dòng)畫(huà)效果示例
這篇文章主要介紹了Python3實(shí)現(xiàn)的畫(huà)圖及加載圖片動(dòng)畫(huà)效果,結(jié)合實(shí)例形式分析了Python3基于tkinter庫(kù)進(jìn)行圖片加載動(dòng)畫(huà)效果的相關(guān)實(shí)現(xiàn)與使用技巧,需要的朋友可以參考下2018-01-01關(guān)于python函數(shù)的建立、調(diào)用、傳參、返回值詳解
這篇文章主要介紹了關(guān)于python函數(shù)的建立、調(diào)用、傳參、返回值詳解,Python?還支持自定義函數(shù),即將一段有規(guī)律的、可重復(fù)使用的代碼定義成函數(shù),從而達(dá)到一次編寫(xiě)多次調(diào)用的目的,需要的朋友可以參考下2023-07-07Django配置Mysql數(shù)據(jù)庫(kù)連接的實(shí)現(xiàn)
本文主要介紹了Django配置Mysql數(shù)據(jù)庫(kù)連接的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03利用Python實(shí)現(xiàn)一個(gè)下班倒計(jì)時(shí)程序
身為打工人,一定是想著下班的那一刻吧,這篇文章主要來(lái)和大家介紹一下如何利用Python實(shí)現(xiàn)一個(gè)下班倒計(jì)時(shí)程序,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-12-12