全文共6398字,預計學習時長16分鐘
Python是許多編程初學者的首選語言,它的語法非常直觀,並且具有支持動態類型的靈活性;此外,它還是一種解釋性語言,可以使用交互式控制臺進行學習。基本上,只使用命令行工具(例如Mac中的Terminal)就能夠開始學習Python,如今macOS系統已經附帶了Python。
學習過程中,我們會逐漸熟悉它的數據結構、控制流、類、函數和其他基本知識。還有一件有趣的事人們不常提起:我們時不時就會遇到Python中的各種首字母縮寫詞。
本文將回顧十個這樣的縮寫詞,包括通用的編程原理以及特定的Python編碼,每個詞都有自己有用有趣的方面。
1. OOP(面向對象編程)
要介紹的第一個縮寫是OOP——面向對象編程,這就是Python所基於的設計。
大家都知道編程本身是關於編碼的,但是程序本身應該是關於數據的。程序需要獲取輸入數據、處理數據和輸出數據。請注意,此處討論的數據是最一般意義上的數據,可以包括表格數、字符串、用戶操作(例如單擊按鈕)、圖像以及任何形式的具有信息的數據。代碼的工作就是處理各種形式的數據,並以所需的方式呈現它們。
為了完成工作,人們需要能夠處理這些數據的代碼,而現代程式語言(包括Python)中的一種常見設計模式就是採用OOP範例。這個想法非常直觀——我們用特定的對象包裝數據。
更具體來講,對象可以保存數據(例如屬性)並且可以操作數據(例如方法)。例如,如果開發一個賽車遊戲,那麼我們可以構建汽車對象,並且每個對象都可以具有特定的屬性,如顏色、最大速度和重量。此外,這些對象還可以進行制動和加速等操作。這些數據的邏輯組織以對象(汽車)為中心。
下面來看一下Python中的特定示例。可以使用內置的str類包裝字符串數據,人們不僅可以使用字符串對象傳遞字符串數據,還可以改變字符串的表示方式。請看一個非常瑣碎的示例。
>>># Create avariable of str type
... hello ="HelloPython!"
...
... # Send the data toa function call
... print(hello)
...
... # Manipulate thestring data with string methods
... hello_lower = hello.lower()
... hello_upper = hello.upper()
... print('lowercased:', hello_lower)
... print('uppercased:', hello_upper)
...
HelloPython!
lowercased: hello python!
uppercased: HELLOPYTHON!
字符串數據處理
2.DRY(不要重複自己)
DRY(不要重複自己)的原理是每個程式設計師都應該實踐的最基本的規則之一。其含義很簡單:如果發現代碼中有任何重複,那麼就表明需要進行一些重構,以實現最大程度地減少重複代碼,或在可能的情況下完全刪除任何重複信號。
以下示例通過應用DRY原理展示了一些代碼的重構:
defdo_something(item):
pass
# Repetativework
do_something(item0)
do_something(item1)
do_something(item2)
# Apply DRY
for item in (item0, item1,item3):
do_something(item)
不要重複自己
代碼重構的另一種可能情況是:發現自己要處理一堆具有相同結構的數據。應該考慮使用自己的類來處理這些數據,而不是使用一系列的字典、列表或元組來存儲每個人的數據。這不僅可以使程式設計師本人的代碼不易出現錯誤,而且對代碼長期可維護性也很有益處。
3. PIP(Python包安裝和管理工具)
Python受歡迎的最重要因素是其開放原始碼的特性,這種特性帶來了大量免費的Python軟體包。根據維基百科介紹,在Python軟體包索引(PyPI)中索引了235000多個軟體包。
我們可以使用pip工具從PyPI安裝任何軟體包。該安裝過程非常輕鬆,只需在命令或終端中使用一行代碼即可。以下代碼段總結了一些常用用法。想要了解有關pip工具用法的更多信息,可以訪問其官方網站:https://pip.pypa.io/en/stable/user_guide/。
# install latest version
pip install package_name
# install aparticular version
pip install package_name==version_number
# to uninstall apackage
pip uninstall package_name
# to show installedpackages
pip list
# to show theinformation about a particular package
pip show package_name
# to install alist of dependencies, such as to clone a virtual environment
pip install -rrequirements.txt
PIP 使用示例
4. LEGB(函數內部作用域,函數內部與內嵌函數之間,全局作用域和內置作用域)
LEGB規則指的是Python中的變量查找順序,如下圖所示。具體來說,當解釋器嘗試解析變量時,Python具有四層作用域——了解將哪些值綁定到變量。
首先從內部範圍開始,該範圍可以是函數或類。如果解釋器為該變量找到了相應的綁定值,那麼它將停止查找並使用具有該特定值的變量。
否則,它將在更高層次上查找——函數內部與內嵌函數之間。這一範圍僅存在於函數的嵌套結構中。當在另一個函數中聲明一個函數時,我們將內部函數稱為內部函數,將外部函數稱為外部函數。當解釋器嘗試解析內部函數範圍內使用的變量時,如果無法在局部範圍內解析,它將進入封閉範圍,即外部函數的局部範圍。
如果仍然無法解析封閉範圍內的變量,它將轉到全局範圍。全局作用域通常是模塊級別,通常是獨立的Python文件。值得注意的是,將包導入當前文件時,導入中的函數和類也將成為全局範圍的一部分。內置作用域是啟動解釋器時要加載的函數、類和其他模塊,以使這些最基本的對象始終可用(例如print和其他內置函數)。
5. MRO(方法解析順序)
方法解析順序表示Python或程式語言通常如何解析方法或屬性。上面討論的LEGB規則關注的是解決變量,而MRO不同,它關注的是對象以及對象的方法調用或特定屬性的獲取如何解決。
MRO主要是在多繼承的上下文中討論的——從多個類(即超類)和/或繼承的多層繼承的類(即子類)。因為子類和超類都共享一些具有可能不同實現的通用方法,所以Python解釋器需要一種機制來確定在特定調用中應使用哪種方法或屬性,而這正是MRO負責的。
>>>classX:
... defbin(self):
... print(f"bin called in X")
...
... classY(X):
... defgo(self):
... print(f"go called Y")
...
... classZ(X):
... defgo(self):
... print(f"go called Z")
...
... classW(Y, Z):
... defbin(self):
... super().bin()
... print(f"bin called W")
...
... defbingo(self):
... self.bin()
... self.go()
...
... w =W()
... w.bingo()
...
bin called inX
bin called W
go called Y
方法解析順序
對於W類的實例(第22行),當我們調用bingo()方法時,此方法在其自己的類中解析,因為它是在類中定義的(第18-20行)。但是,此方法將進一步調用bin()和go()方法。
以類似的方式,bin()方法在其自己的類中得到解析,但它調用超類的bin()方法,如第15行所示。但是在其直接超類(即Y和Z)中,都未實現 bin()方法,因此Python會比超類的超類(如X)高一個級別,在該超類中實現並調用bin()方法。
值得注意的是,對於W的go()方法,其兩個超類都實現了此方法,但是如你所見,這僅調用了Y類中使用的實現。因為當定義W類時,繼承順序為Y和Z,這將使MRO遵循相同的順序。
與此相關的是,可以使用特殊方法__mro__找出特定類的MRO。另外,為了展示類繼承順序的重要性,我們創建了另一個類,其中Z類位於Y類之前,這會更改W_類的MRO。
>>>print('W Class MRO:', W.__mro__)
...
... classW_(Z, Y):
... pass
...
... print('W_ Class MRO:', W_.__mro__)
...
WClassMRO: (<class '__main__.W'>, <class '__main__.Y'>, <class '__main__.Z'>, <class '__main__.X'>, <class 'object'>)
W_ClassMRO: (<class '__main__.W_'>, <class '__main__.Z'>, <class '__main__.Y'>, <class '__main__.X'>, <class 'object'>)
特殊方法 __mro__
6.&7. EAFP(請求寬恕比許可更容易)和LBYL(事先檢查)
EAFP(請求寬恕比許可更容易)編碼風格是Python賴以生存的基礎。由於Python是一種動態程式語言,因此在運行時可以實現對現有實例對象,類甚至模塊的實現以及修改。因此,建議在假定特定屬性或功能可用的情況下編寫代碼。
換句話說,如果某些代碼可能存在特定問題,那麼就讓問題浮出水面並相應地解決它們。通過應用EAFP規則,如果我們想更進一步,就可以簡單地使用try ... except語句編寫特定代碼,以處理代碼可能引發的潛在異常。總之,宗旨就是如果發生意外情況,事後處理。
與EAFP原理相反,還有另一種稱為LBYL的編碼樣式,它代表「事先檢查」。使用這種編碼方式,程式設計師可以在運行某些代碼之前排除所有可能的不良情況。因此,就可以在更多遵循LBYL原則的項目中看到更多if語句。這種編碼樣式就是盡力以特定的方式防止一切問題。
以下代碼段顯示了使用EAFP與LBYL的可能方案。使用EAFP編碼樣式,只需將代碼和預期的可能異常包裝在try…except語句中,同時使用LBYL編碼樣式,必須使用內省法和值檢查來驗證除法之前的適用條件。
正如大家看到的,EAFP代碼看起來更乾淨,並且沒有創建嵌套結構。當然,如果願意的話,也可以在項目中應用LBYL,最終項目仍然將以類似的方式工作。
defwith_EAFP_divide_ten_by(number):
try:
print(f'10 divided by {number} is {10/ number}.')
exceptZeroDivisionError:
print("You can'tdivide zero.")
exceptTypeError:
print("You canonly divide a number.")
defwith_LBYL_divide_ten_by(number):
ifisinstance(number, int) orisinstance(number, float):
if number ==0:
print("You can'tdivide zero.")
else:
print(f'10 divided by {number} is {10/ number}.')
else:
print("You canonly divide a number.")
EAFP vs. LBYL
8. PEP(Python增強建議書)
上一節大體討論了編碼樣式,但是最有影響力的Python編碼風格指南之一就是PEP 8——Python增強建議書#8,由BDFL(將在下文討論)和其他幾個Python核心維護者編寫。
PEP涵蓋了很多內容——所有與Python相關的內容,可以在官方網站上找到整個列表(https://www.python.org/dev/peps/。這裡列出了一些著名的文章:
· PEP 8: Style Guide for Python Code
· PEP 257: Docstring Conventions
· PEP 20: The Zen of Python
· PEP 498: Literal String Interpolation
· PEP 202: List Comprehensions
· PEP 405: Python Virtual Environment
9. BDFL(仁慈的獨裁者)
什麼是BDFL?以下是維基百科的定義:仁慈的獨裁者(BDFL)是少數開源軟體開發領導者的頭銜,他們通常是在社區中的爭端或爭論中保留最終決定權的項目創始人。
儘管這個定義通常適用於開源軟體開發,但它最初是在Python社區中使用的,是指代Python程式語言的創建者Guido van Rossum(GvR)的一種方式。他在擔任BDFL角色20多年之後,於2018年卸任,你可以在維基百科上找到更多關於BDFL的故事。
10. REPL(「讀取-求值-輸出」循環)
在筆者看來,REPL(「讀取-求值-輸出」循環)正是使學習Python如此輕鬆的便捷工具。我們可以像使用命令或終端窗口一樣開始簡單地學習Python編碼,可以使用pip工具如前所示安裝軟體包。更重要的是,無需編寫任何其他程式語言可能需要的IDE工具即可立即編寫Python代碼的第一行(例如可能應該是這行代碼:print(「Hello World!」))。
來快速看一下它的樣子吧:
>>>print("HelloWorld!")
HelloWorld!
>>>3*2
6
>>>type(5)
<class'int'>
REPL示例
REPL工作流程非常簡單——閱讀代碼,對其進行評估,並在控制臺中列印評估中的所有適用結果,然後循環重複這三個步驟以探索Python的各種功能。REPL在標準Python或其他常見的Python開發工具(例如ipython)中作為默認模式實現,這也是著名的Python學習和編碼工具——Jupiter Notebook的基礎。
Python是一種由BDFL GvR創建的靈活而強大的OOP語言。利用PIP,我們可以輕鬆地管理Python軟體包,並通過REPL在控制臺中學習語言和各種軟體包。使用Python進行編碼時,我們希望遵循PEP 8中概述的樣式。其他重要的編碼原理包括DRY和EAFP。如果願意的話,也可以在編碼中做一些LBYL。LEGB規則和MRO將幫助大家了解如何解析變量、屬性和函數以使你的代碼按預期運行。
這些Python「黑話」,你學會了嗎?
留言點讚關注
我們一起分享AI學習與發展的乾貨
如轉載,請後臺留言,遵守轉載規範