Python寫出漂亮Python 代碼的19條準則,你學會了嗎?

2020-11-14 小布講堂

通常,當我們在學校學習時,編程美學不是一個關鍵問題。用 Python 寫代碼時,個人也會遵循自己的風格。然而,當我們必須花大把時間來理解一個人的隱式代碼時,這項工作肯定不受歡迎,這種情況同樣可能發生在別人閱讀我們的代碼時。所以,讓我們聚焦 Python 之禪和一些改進技巧,從而解決問題。


對於此前沒聽說過的人,請在 Python 解釋器中鍵入並執行import this,會出現由 Tim Peters 撰寫的 19 條指導原則:

  1. 優美勝於醜陋;
  2. 明了勝於晦澀;
  3. 簡單勝於複雜;
  4. 複雜勝於晦澀;
  5. 扁平勝於嵌套;
  6. 間隔勝於緊湊;
  7. 可讀性很重要;讀
  8. 特例不足以特殊到違背這些原則;
  9. 實用性勝過純粹;
  10. 永遠不要默默地忽視錯誤;
  11. 除非明確需要這樣做;
  12. 面對模稜兩可,拒絕猜測;
  13. 解決問題最直接的方法應該有一種,最好只有一種;
  14. 當然這是沒法一蹴而就的,除非你是荷蘭人;
  15. 做也許好過不做;
  16. 但不想就做還不如不做;
  17. 如果方案難以描述明白,那麼一定是個糟糕的方案;
  18. 如果實現容易描述,那可能是個好方案;
  19. 命名空間是一種絕妙的理念,多加利用!

在這篇文章中,我將分享自己對這些格言的理解以及我學到的一些有用的 Python 技巧。

1優美勝於醜陋

Python 具有語法簡單、代碼可讀性強和命令類似英語等特點,這讓編寫 Python 代碼比使用其他程式語言更容易、更高效。例如,使用or and和|| &&構建語義相同的表達式:


# &&, ||if a == 0 && b == 1 || c == True:# and, orif a == 0 and b == 1 or c == True:# 這兩個邏輯表達式在 Python 中是相同的# 從語義的角度來看,可以使用選擇操作符來構造完全相同的表達式。

此外,代碼的布局和組成非常重要,有大量資源涉及這個主題。下面是最受歡迎也是我最喜歡的一個:PEP 8——Python 代碼風格指南。

https://www.python.org/dev/peps/pep-0008/

瀏覽完 PEP8 後,看看下面這些文章,其中展示了一些亮點和應用:

  • 如何參照 PEP 8 編寫漂亮的 Python 代碼https://realpython.com/python-pep8/
  • 優雅的 Python 與 PEP8https://medium.com/@mariasurmenok/stylish-python-with-pep8-c3ca93531418
  • PEP-8 的陷阱https://medium.com/@ian.reinert/the-pitfalls-of-pep-8-b6108b006ed9

永遠不要弄亂你的代碼。要優雅而美麗。

2明了勝於晦澀

在 Python 中,良好的命名約定不僅可以提升你的課堂成績,而且還能讓你的代碼更明了。幸運的是,你能在 PEP8 中找到一些指導原則,我想在下面強調其中的一些要點。

https://www.python.org/dev/peps/pep-0008/

  • 一般來說,避免使用以下名稱:
  • 太寬泛,如my_list;
  • 太冗長,如list_of_machine_learning_data_set;
  • 太模糊,如「1」、「I」、「o」、「O」。
  • 包 / 模塊名應該全部小寫:
  • 首選使用一個單詞命名;
  • 當需要使用多個單詞時,使用下劃線分割它們。
  • 類名應遵循 UpperCaseCamelCase 規範
  • 變量\方法\函數應該採用小寫(如果需要,用下劃線分割)
  • 常量名必須全大寫(如果需要,用下劃線分割)

一切都必須清晰易懂。

3簡單勝於複雜

簡單比複雜更難:你必須付出巨大艱辛,化繁為簡。但這一切到最後都是值得的,因為一旦你做到了,你便能創造奇蹟。——賈伯斯

很多時候,在處理迭代器時,我們還需要保存迭代計數。Python 通過提供一個名為enumerate()的內置函數簡化這一任務。以下是一種不成熟的方法,然後是推薦方法:

words = ['Hannibal', 'Hanny', 'Steeve']# 不成熟的方法index = 0for word in words: print(index, word) index += 1# 推薦方法for index, word in enumerate(words): print(index, word)

另一個示例是使用內置的zip()函數,該函數創建一個迭代器,對來自兩個或多個迭代器的元素進行配對。你可以使用它來快速有效地解決常見的編程問題,比如創建字典。

subjects = ['math', 'chemistry', 'biology', 'pyhsics']grades = ['100', '83', '90', '92']grades_dict = dict(zip(subjects, grades))print(grades_dict)

化繁為簡的能力就是消除不必要的東西,保留必要的東西。

4複雜勝於晦澀

複雜(complex )和晦澀(complicated )的區別在於,複雜是指組件的系統層級,晦澀是指難度高。

有時候,儘管我們試圖讓任務變得簡單和傻瓜化,結果可能仍然很糟。

在這種情況下,編程優化變得很有必要,我最喜歡的學習方法是完成 coding challenge websites 上的工作。你可以查看其他人的解決方案,甚至能受到更好算法的啟發。

https://www.freecodecamp.org/news/the-10-most-popular-coding-challenge-websites-of-2016-fb8a5672d22f/

對於入門,HackerRank 提供了適合新手程式設計師的各種級別任務,這非常棒。之後,可以去嘗試更專業的網站,比如 Coderbyte 和 Topcoder。


5扁平勝於嵌套

嵌套模塊在 Python 中並不常見——至少我之前沒有見過像module.class.subclass.function這樣的東西——可讀性不好。雖然在另一個子模塊中構建子模塊可能會減少代碼行數,但我們不希望用戶被不直觀的語法所困擾。

6間隔勝於緊湊

不要在一行中插入太多代碼,這會給讀者帶來壓力。建議最大行長度 79 個字符。這樣,當使用代碼評審工具時,編輯器窗口寬度限制才能很好工作。

使用 Python 從 Unsplash 下載圖片

7可讀性很重要

代碼的閱讀次數比編寫次數多。考慮下縮進,它讓代碼更容易閱讀,比較下面的代碼:money = 10000000print("I earn", money, "dollars by writing on medium.")money = 10_000_000print(f"I earn {money} dollars by writing on medium.")

在本例中,代碼結果相同,但是後一段代碼通過使用下劃線佔位符和 f-string 提供了更好的可讀性。在 Python 3.6 發布後,f-string 開始讓格式化變得更簡單,並且在處理包含更多變量的更長的句子時更強大。

一個作家的風格不應該在他的思想和讀者的思想間設置障礙。

8特例不足以特殊到違背這些原則

關鍵是為一般情況提供一貫支持,嘗試將一個繁瑣的項目重新組織成一個簡單形式。例如,根據其功能,結構化類的代碼或將其分類到不同的文件中,即使 Python 並不強迫你這樣做。由於 Python 是一種多範式程式語言,解決問題的一個強大方法是創建對象,這就是所謂的面向對象編程。

面向對象編程是一種組織程序結構的編程範式,讓屬性和行為可以被看作是單獨對象。它的優點是直觀和易於操作,許多教程都很好地解釋了這些概念。

9實用性勝過純粹

這句格言與前一句相矛盾,它提醒我們保持它們之間的平衡

10永遠不要默默地忽視錯誤

放過錯誤最終會留下隱式 Bug,並且這些 Bug 更難被發現。Python 提供了健壯的錯誤處理,與其他語言相比,程式設計師使用該工具並不難。

try: x = int(input("Please enter an Integer: "))except ValueError: print("Oops! This is not an Integer.")except Exception as err: print(err)else: print('You did it! Great job!')finally: print('ヽ(✿゚▽゚)ノ')# 1. 這段代碼可能中斷。# 2. 如果出現值錯誤就會觸發。# 3. 處理值錯誤之外的錯誤。# 4. 如果沒有觸發錯誤就執行。# 5. 不管是否觸發錯誤都執行。

根據 Python 文檔:「即使一個語句或表達式在語法上是正確的,在試圖執行它時也可能會導致錯誤。」特別是對於大型項目,我們不希望在耗時的計算後,代碼崩潰。這就是異常管理的魅力所在。

11除非明確需要這樣做

在某些情況下,小錯誤不會困擾你。不過,也許你想捕獲特定錯誤。要獲得關於特定錯誤消息的更多細節,我建議閱讀官方的內置異常文檔並找到你需要的內容。

https://docs.python.org/3/library/exceptions.html

12面對模稜兩可,拒絕猜測

重要的是要不斷學習,享受挑戰,容忍歧義。我們都不知道最終會怎樣。——瑪蒂娜·霍納

這句話優雅而抒情,但在編程中不是一個好的隱喻。歧義可能是指不清楚的語法、複雜的程序結構或觸發錯誤消息的錯誤。例如,第一次使用numpy模塊時的一個簡單錯誤:

import numpy as npa = np.arange(5)print(a < 3)if a < 3: print('smaller than 3')

ValueError: 具有多個元素的數組的真值不明確,請使用 a.any() 或 a.all()

如果執行上面代碼,你將在輸出中發現一個由 5 個布爾值組成的數組,表明值在 3 以下。因此,if語句不可能確定狀態。消息中顯示的內置函數.all() 和.any()用於代替 And/Or。


import numpy as npa = np.array([True, True, True])b = np.array([False, True, True])c = np.array([False, False, False])print(a.all())print(a.any())print(b.all())print(b.any())print(c.all())print(c.any())

輸出表明,.all()僅在所有項都為True時才返回True,而.any()在有一項為True時就返回True。

13解決問題最直接的方法應該有一種,最好只有一種

想想為什麼 Python 被描述為一種易於學習的程式語言。Python 具有非凡的內置函數 / 庫和高度的可擴展性,它鼓勵程式設計師優雅地編寫代碼。儘管有更多的解決方案可以提供靈活性,但對於同一個問題,它們可能會花費更多時間。


輸入 import antigravity 並執行

14當然這是沒法一蹴而就的,除非你是荷蘭人

Python 之父 Guido van Rossum 是一位荷蘭程式設計師,他讓這句格言變得無可爭議。你不會聲稱自己比他更了解 Python……至少我不會。

照片來自 GitHub

15做也許好過不做

你可以拖延,但時間不會,失去的時間一去不復返。——班傑明·富蘭克林

對於那些像我一樣患有拖延症,正在尋求改變的人,看看這個,和恐慌怪獸合作。

https://embed.ted.com/talks/tim_urban_inside_the_mind_of_a_master_procrastinator

另一方面,這個格言的另一個方面是阻止你過度計劃,這並不比看 Netflix 更有效率。

拖延和過度計劃的共同特徵就是「什麼都做不了。」

16不想就做還不如不做

「做也許好過不做」並不意味著計劃沒用。把你的想法寫下來,設定一個要徵服的目標,比不想就做要好。

例如,我通常在每個星期天花一個小時來制定我的周計劃,並在睡覺前更新我明天的計劃,看看有什麼需要推遲的事情。

17如果解決方案難以解釋清楚,那一定很糟糕

回想一下「複雜勝於晦澀」的理念。通常,晦澀的代碼意味著弱設計,特別是在像 Python 這樣的高級程式語言中。

然而,在某些情況下,其領域知識的複雜性可能會讓實現難以解釋,而如何優化讓其明晰易懂至關重要。這裡有一個規劃項目指南,可以給你提供幫助。

https://docs.python-guide.org/writing/structure/

18如果實現容易描述,那可能是個好方案

使設計(甚至人們的生活)更容易,即使背景知識可能很深刻,這是編程的專業知識,我認為也是編程中最困難的部分。

利用 Python 的簡單性和可讀性來實現一些瘋狂的想法。

19命名空間是一種絕妙的理念,多加利用!

最後但同樣重要的是,命名空間是一組符號,用於組織各種對象,以便這些對象可以通過惟一的名稱引用。在 Python 中,命名空間是由以下元素組成的系統:

  1. 內置命名空間:可以在不創建自定義函數或導入模塊(如print()函數)的情況下調用。
  2. 全局命名空間:當用戶創建一個類或函數時,將創建一個全局命名空間。
  3. 局部命名空間:局部作用域中的命名空間。

相關焦點

  • Python居然能寫出豆瓣、油管等,這些小而美的應用/App!
    很多你所喜愛的軟體或者正在用的,可能就是用python所實現的應用目前使用python較多的還是國外的應用,有哪些你能想到是用python寫的呢?1.豆瓣創始人阿北表示「python很簡潔,用縮位省去了我很多時間,以前 { } ; 敲了十幾年了,現在想起來真是不堪回首!」2.照片牆Instagram以一種快速、美妙和有趣的方式讓你隨時抓拍隨時分享圖片,前任美國總統歐巴馬也曾用過這個小軟體。
  • 你真的懂python嗎?
    在人工智慧盛行的今天,有一門程式語言也悄然的流行了起來,那就是大名鼎鼎的python。或許你僅僅知道它只是一門計算機程式語言,但你知道它是怎麼發明的嗎?它是如何在深度學習領域佔有如此重要的地位嗎?下面將帶大家走入python的世界。
  • 如何用PYTHON代碼寫出音樂
    說到用代碼寫曲子,有一個東西大家一定要了解就是MIDI。MIDI是一種樂器數字接口,是編曲界最廣泛的音樂標準格式。MIDI並不是真正意義上的音樂文件,大家可以把它理解成樂譜,需要有環境編譯MIDI文件,才可以生成音樂。這個關係有點像代碼和編譯器的關係。
  • 《笨辦法學python》再笨的人都能學會python
    《笨辦法學python》再笨的人都能學會python每一章的格式基本相同,以代碼習題開始,按照說明編寫代碼,運行並檢查結果,然後再做附加練習。在本書的幫助下,你將通過完成下面這些非常簡單的事情來學會一門程式語言
  • 編程屋Python課堂-體驗課
    這些準則被稱為「Python格言」。在Python解釋器內運行import this可以獲得完整的列表。02其實python非常適合初學者入門。相比較其他不少主流程式語言,有更好的可讀性,因此上手相對容易。自帶的各種模塊加上豐富的第三方模塊,免去了很多「重複造輪子」的工作,可以更快地寫出東西。配置開發環境也不是很複雜,mac和linux都內置了python。
  • python格式化代碼只懂autopep8?這裡有更好的
    不需要再對著pep8標準扣字眼來修改自己代碼減少了組內不必要的討論,專注於項目功能代碼風格更統一,github上傳代碼衝突更少幫助多人開發協調代碼規範因此大多數公司招聘python開發人員時將了解pep8
  • 斯坦福教授發現,玩這兩個遊戲能帶你學會python,附教程
    這是兩個很有趣的python編程遊戲,分別是:Python遊戲彈球、Python火柴人逃出遊戲。什麼時候能玩會這兩個遊戲,就能學會python編程。它會幫助你安裝python,開啟PythonShell程序以及執行簡單計算,在屏幕上列印文本還有創建列表,用if語句和for循環執行簡單的過程控制操作。你還將學會如何用函數來重用代碼,基本的類和對象的知識,還有其他眾多的Python內建函數和模塊的介紹。
  • 謹記四條規則,便可寫出完美的Python命令行程序
    因此,我建議你遵循以下四條規則:  儘可能提供默認參數值所有錯誤情況必須處理(例如,參數缺失,類型錯誤,找不到文件)所有參數和選項必須有文檔不是立即完成的任務應當顯示進度條  舉個簡單的例子  我們把這些規則應用到一個具體的例子上。這個腳本可以使用凱撒加密法加密和解密消息。
  • 如何寫出更具有Python風格的代碼,五分鐘教會你
    PEP8,而是要求遵循其中的大多數規則,何況現在有很多自動格式化的工具,足以讓你的代碼更加美觀,我們的 Python 之父也說過:閱讀代碼的頻率遠遠高於寫代碼的頻率,他是如此的正確!儘管代碼注釋是個好方法,但是代碼的風格也需要加以調整,比如變量 i , j , count 等即使第一次出現時寫了注釋,也不能保證後面你仍然記得住,這樣來看就浪費了寶貴的時間。
  • 假如這篇文章都不能讓你學通python,編程界你怕是進不來了
    當我們學會知識之後,基本概念就會回來找我們算帳,出錯一次劍,就記一次帳,帳本慢慢變厚的過程就是我們向基本概念靠攏的過程。當我們掌握了知識最基本的概念之後,我們就開始還帳了,這時,帳本就開始慢慢薄了一旦基礎概念掌握熟練了,日後無論做什麼都會更加輕鬆,像python在別的方面的應用,如數據分析,人工智慧,爬蟲等等,都是以python為基本內核的。
  • 假如這篇文章都不能讓你學通python,編程界你恐怕是進不來
    當我們學會知識之後,基本概念就會回來找我們算帳,出錯一次劍,就記一次帳,帳本慢慢變厚的過程就是我們向基本概念靠攏的過程。當我們掌握了知識最基本的概念之後,我們就開始還帳了,這時,帳本就開始慢慢薄了一旦基礎概念掌握熟練了,日後無論做什麼都會更加輕鬆,像python在別的方面的應用,如數據分析,人工智慧,爬蟲等等,都是以python為基本內核的。
  • 為什麼很多學習python的人能看懂代碼,但自己動手卻寫不出來呢?
    關於這個問題,想必是很多人都有的心理歷程或者是「說辭」,但其實真正的原因並不是你們所說的「我能看懂,但是讓我寫卻寫不出來」,真正的原因和問題是在於你當時學習的時候就沒有學會,也不懂如何正確的學習python編程。根據這個問題的具體原因以及如何去破解這樣的問題,我今天會在下面跟大家詳細說明。
  • 看完本文若不能讓你學通python,豪言我願永久退出IT界
    當我們學會知識之後,基本概念就會回來找我們算帳,出錯一次劍,就記一次帳,帳本慢慢變厚的過程就是我們向基本概念靠攏的過程。書中採用作者獨創的「活代碼」教學方法,揭示了Python這一語言的強大功能。與此同時,本書述提供了大量的示例代碼和編程技巧與提示,幫助讀者搭建良好的知識結構,養成良好的編程習慣,指導讀者如何避免常見的編程錯誤以及寫出高效、可靠的應用程式。
  • 學會python文件操作,滑鼠好像沒用了,學習python第10天
    電影是人類對未來的嚮往,在《黑客帝國》中,我們看到了一個數位化的社會,而當你學會python文件操作,你也就離你嚮往的黑客近一點了,用程序來直接影響電腦上的其他文件,只需要幾行代碼就搞定。而使用python文件操作來寫總結過程跟上述是類似的,但是其分為三個步驟:1、打開文件或者新建一個文件;2、讀/寫數據進文件中;3、關閉文件。下面羽憶教程為你介紹具體的編程操作流程。
  • 怎麼學習python,一個月入門,教你成為python大神
    ,這時你需要查查各個專業領域的python要求。python爬蟲書籍,一般來說裡面會有python基礎部分,同理你只要在官方文檔裡找這部分知識學習。其它回答裡也提到了在重複練習中學習python,這點我是非常認同的。輸出是最好的輸入,程式語言雖然注重邏輯,但更需要學習者不斷地動手敲代碼。從一開始,你要學會如何搭建python環境,選擇什麼樣的開發環境(IDE)。這些都可以去網上查,慢一點的折騰兩三天,快一點的一天不到就能搞定。
  • Python這麼火,你確定不要學?
    「我高中畢業可以學習編程嗎?」「我對遊戲感興趣,但是不想上編程課,可以寫出來類似王者的遊戲嗎?」「我英文不好,能學會編程嗎?」「學習編程有速成的嗎?」嗨,兄臺,醒醒好嗎?這個遠景怕是有點太理想了,咱現實的好嗎?
  • 用python代碼安裝軟體所需要的工具的介紹
    用python代碼安裝軟體所需要的工具的介紹 python代碼是計算機語言中經常使用的計算機語言,那麼我們對python代碼的實際相關功能也相當的了解嗎?如果你對其存在疑問,你就可以觀看我們的文章。
  • 他說,懂中文就能學會Python,但需要這個工具
    懂中文你就能學會python,但你需要一些靠譜的工具。python作為一門十分容易上手的程式語言,連小學生都在學習,所以,不管你是從事什麼工作,都可以學會這門程式語言。現在告訴你,懂中文就能學會python編程。
  • Python趣味打怪:60秒學會一個例子,147段代碼助你從入門到大師
    段簡單易懂的代碼,介紹了Python的基礎語法、功能。其中,有常用知識的總結,隨查隨用:從正則化起手式到簡單爬蟲的實現,也都一步步用代碼鋪開:△urllib為內置模塊,推薦第三方庫requests當然啦,學習Python,怎麼能忽略三大利器:迭代器,生成器,裝飾器。你問啥是裝飾器?
  • 一行代碼實現Python並行處理
    問題在於…首先,你需要一個樣板類;其次,你需要一個隊列來傳遞對象;而且,你還需要在通道兩端都構建相應的方法來協助其工作(如果需想要進行雙向通信或是保存結果還需要再引入一個隊列)。你可以針對 IO 密集型任務和 CPU 密集型任務來選擇不同的庫。