1.1 物件與類別
今天你會了解到 Python 程式的典型結構。最重要的是: 每個 Python 程式都是由類別和物件組成的。 Python 是一種面向物件的語言,裡面的所有東西都是物件: 數字、字串、函數,甚至是類別本身。
那麼什麼是類別呢?
讓我用個比喻來說明。想像你要製作一艘小船。 首先你要做個圖紙,然後將圖紙交給工廠,依據它來建造船艦。或許建造十艘。其實,無論多少艘都可以。關鍵是,依據同一張圖紙可建造數十艘相同的船。
在 Python 編程中也是一樣的。
圖紙
程式設計師就像設計師。設計師繪製圖紙,而 Python 程式設計師撰寫類別。然後基於圖紙創建零件,基於類別創建物件。
我們先撰寫類別(製作圖紙),然後在程式執行時, Python 根據這些類別創建物件。就像船是依據圖紙建造的一樣。
圖紙有一張,但船艦可能有很多。船艦不同,有不同的名字,運送不同的貨物。但它們非常相似:它們都是具有相同結構的船艦,能執行類似的任務。
或這樣的比喻...
蟻巢
蟻巢是一個很好的物件互動的例子。簡單的 蟻巢中有三種類別的螞蟻:女王、士兵和工人螞蟻。
每種類別的螞蟻數量不同。整個蟻巢只有一隻女王,幾十隻士兵,而數百隻工人螞蟻。三個類別和數百個物件。螞蟻按照嚴格的規則與其他螞蟻和其他類別的螞蟻互動。
這是一個完美的例子。在典型的程式中也是如此。有一個主要物件,創造其他類別的物件。物件開始與程式的「外部世界」互動。這些物件內部有嚴格定義的行為。
這兩個解釋是同一枚硬幣的兩面。真相在中間。第一個例子(關於圖紙和船艦)展示了類別和該類別物件之間的關係。這個比喻非常強烈。第二個例子(關於蟻巢)展示了在程式執行時存在的物件和撰寫的類別之間的關係。
首先,你必須為程式中所有的物件撰寫類別,然後描述它們之間的互動。聽起來有點複雜,但比你想像的要簡單。
在 Python 中,所有的實體在程式執行時都是物件,而撰寫程式就是描述物件之間互動方式的過程。物件會呼叫彼此的方法並傳遞所需的資料。
文件
那如何知道要在方法中傳遞哪些資料呢?這一切都已經提前為你想好了。
通常每個類別都有描述,說明它是用來做什麼的。通常每個公共方法都有說明:它做什麼以及需要傳遞哪些資料。
要使用一個類別,你需要大致了解它的功能。還需要準確知道每個方法的功能。而您不需要知道它是如何運作的。就像魔杖一樣。
讓我們看看這段代碼 - 複製檔案:
src = open('source.txt', 'r')
dst = open('destination.txt', 'w')
for line in src:
dst.write(line)
src.close()
dst.close()
如果逐行閱讀這段代碼,你可以大致猜出它在做什麼。雖然需要一些經驗和練習。過一段時間,你會覺得這段代碼熟悉且易懂。
1.2. 程式設計
程式設計是一種藝術。既簡單又複雜。簡單,因為沒有嚴格的法律:凡是未被禁止的都是允許的。而複雜也正是出於這個原因:有很多方法可以做某事,很難找到最佳的。
設計程式就像寫書。一方面,你只是在寫字母、單詞、句子。另一方面,情節、角色性格、內在矛盾、衝突、敘述風格、懸念等都很重要。
最重要的是明白,你是為誰寫代碼的。記住,你的代碼是為其他程式設計師準備的。
開發任何產品的過程都是對其進行修改:在這裡添加,在那裡刪除,重新製作。就這樣,通過小的迭代,誕生了大型、巨大、巨大的專案。
代碼的主要要求是— 它必須對其他程序员来说是清晰且可理解的。 錯誤的但可理解的代碼可以被修正。 正確且難以理解的代碼則無法被改進。它只能被丟棄。
那麼如何寫出好的和容易理解的代碼呢?
有三件事情需要做到:
- 在方法中寫出好的和易於理解的代碼——這是最簡單的。
- 決定程式中應該有哪些實體。
- 正確地將程式分割成邏輯部分。
這些概念背後是什麼?
在方法中寫出好的代碼
如果你具有基礎的英語水平,你可能會注意到代碼有時候很容易讀懂:就像英語中的句子:
-
class Cat(Pet)
– 貓類別繼承了寵物類別。 while stream
: – 當 stream 不為空時 ...-
a if a < b else b
– 如果a
小於b
,則返回a
,否則返回b
。
這是故意設計的。Python 是少數幾種語言中,容易撰寫自文件化代碼的語言:代碼在沒有註解的情況下也能被理解。在好的 Python 代碼中,許多方法讀起來就像英語句子。
當你寫代碼時,你的目標也是讓代碼儘可能簡單和簡練。只要考慮你的代碼有多容易閱讀,你就會朝著正確的方向前進。
在 Python 中,容易閱讀的代碼被認為是好的代碼。通常每個方法應該完整地顯示在螢幕上(方法的長度為 20-30 行)。這是整個 Python 社區的標準。 如果代碼可以被改進,那麼就應該被改進。
學習寫出好代碼的最佳方法是持續的實踐。多寫代碼,研究他人的代碼,請求更有經驗的同事審查你的代碼。要記住,一旦你告訴自己「這樣就行了」,你的成長就會停滯。
決定程式中應該有哪些實體
你需要寫出其他程式設計師能夠理解的代碼。如果在設計程式時 10 個程式設計師中有 9 個會在程式中創建類別 A、B 和 C,那麼你也應該在你的程式中創建類別 A、B 和 C。你應該寫出其他人能理解的代碼。
優秀的、有效的、快速的、非標準的代碼——是不好的代碼。
你需要研究其他人的專案:這是最好的、最快的也是最簡單的方式,去獲取 IT 產業累積多年的智慧。
順便說一下,你手邊已經有一個很棒的、受歡迎的、文檔齊全的專案——Python SDK。從它開始。
分析類別和類別的結構。思考為什麼有些方法是靜態的,而其他的不是。為什麼方法有這樣的參數,而不是其他的。為什麼是這些方法,為什麼類別叫這些名字並位於這些包裝中。
當你開始理解這些問題的答案時,你就能寫出其他人可以理解的代碼。
然而,我要警告你不要去分析 Python SDK 方法中的代碼。許多方法的代碼經過重寫以最大化執行速度——其可讀性是一個問題。
正確地將程式分割成邏輯部分
任何程式通常都會被分割成部分或模塊。每個部分負責程式的一個方面。
例如,計算機有系統單元、顯示器、鍵盤,這些都是獨立且依賴性較低的部分。而且它們的互動是標準化的:USB、HDMI 等。所以如果你把咖啡灑在鍵盤上,你可以直接在水龍頭下清洗,晾乾後繼續使用。
而筆記本電腦就是一個整體架構的例子:邏輯部分看似存在,但整合程度更高。至於 Macbook Pro,要清潔鍵盤需要拆掉一半的筆記本電腦。而灑在筆記本電腦上的咖啡——是訂購一台新電腦的理由。當然,不是咖啡。
1.3 創建自己的類別
當你開始學習編程時,重要的是從小事開始——學會創建自己的類別。
你當然已經創建過類別,但你需要學會理解程式中應該有哪些類別,它們應該叫什麼名字,應該有什麼方法。以及它們應該如何互動。
實體列表
如果你不知道從何開始,那就從頭開始。
在程式的設計初期,你可以拿張紙寫下程式中應該存在的實體(物件)列表。然後根據這個原則對它們進行編程:每個實體都是一個單獨的類別。
例子
假設你想寫一個下棋遊戲。你需要這樣的實體:棋盤和 6 種棋子。棋子的走法不同,價值不同——合理來說,這是單獨的類別。總之,在一開始,類別越多越好。
要遇到一個初學程式設計師,寫兩個類而不是十個,這種情況很少見。相反,初學者喜歡把十個類寫成兩個,甚至一個。所以更多的類,各位程序员。這樣你的代碼更容易被大家理解,或許除了你自己之外 😛
下棋
假設我們決定寫下棋的類別:這些類別會是怎樣的呢?
棋盤只是個 8x8 的陣列嗎?不如為它創建一個單獨的類,它內部保存一個指向陣列的引用。這樣你就可以在「棋盤」類中加入許多有用的方法,比如檢查格子是空的還是被佔用。
總之,一開始你總可以遵循這個原則:程式有不同的實體,實體有類型。這個類型就是類別。
GO TO FULL VERSION