天天看點

《Python面向對象程式設計指南》——第1部分 用特殊方法實作Python風格的類 第1章 __init__()方法 1.1 隐式的基類——object

本節書摘來自異步社群《python面向對象程式設計指南》一書中的第1章,第1.1節,作者[美]steven f. lott, 張心韬 蘭亮 譯,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

__init__()方法

與python無縫內建——基本特殊方法

屬性通路、特性和修飾符

抽象基類設計的一緻性

可調用對象和上下文的使用

建立容器和集合

建立數值類型

裝飾器和mixins——橫切方面

python風格的類 通過重寫特殊方法來完成對python内部機制的調用,在python中是很普遍的。例如len()函數就可以重寫一個類的__len__()方法。

這意味着對于像(len(x))這樣的通用公共接口,任何類(例如,聲明一個類叫tidy)都可以實作它。任何類都可以重寫一個像__len()__這樣的特殊方法,這樣一種機制構成了python多态機制的一部分;任何實作了__len()__函數的類都會響應通用公共接口(len(x))中的len()函數。

每當定義一個類,可以(而且應該)提供這些特殊方法的實作來與python語言更好地結合。本書的第1部分“用特殊方法實作python風格的類”是對傳統面向對象設計的一種延伸,可以使建立的python類更具python風格。任何一個類都應當與python語言其餘的任何原生部分很好地結合。這樣一來,既可以重用很多其他語言現有的功能和标準庫,而且編寫的包和子產品也将更容易維護和擴充。

在某種程度上,建立的類都可以作為python擴充的形式來實作。開發者都希望自己的類更接近python語言的原生類。這樣一來,在語言之間、标準庫之間以及應用程式之間的代碼差別就能夠最小化。

為了實作更好的可擴充性,python語言提供了大量的特殊方法,它們大緻分為以下幾類。

特性通路(attribute access):這類特殊方法實作了對象的特性通路,使用方式為object.attribute,既可以用來指派,也可以在del語句中執行删除操作。

可調用對象(callables):這個方法的适用對象為參數,就像python内部的len ()函數。(也是應用于參數。)

集合(collections):這類方法提供了很多集合操作的功能。類似這類方法的使用有sequence[index]、mapping[key]和some_set | another_set。

數字(numbers):這類方法提供了大量的數學運算符和比較運算符。可以使用這些方法來擴充python的數字部分。

上下文(context):這類函數通常使用with語句來實作上下文的管理。

疊代器(iterator):可以使用這類方法定義疊代器,通常不需要考慮這部分的擴充,因為生成器(generator)已經提供了非常優雅的實作。然而,我們仍會探究如何建立自己的疊代器。

在python 3 object oriented programming一書中已經介紹了這些特殊方法中的一部分,以下我們将重新回顧這些主題并對其他屬于基本範疇的特殊方法進行深入介紹。

盡管是基礎的範疇,仍可以針對其他比較深入的主題進行讨論。這裡将會以基礎的幾個特殊方法作為開始,後續會讨論一些進階的特殊方法。

__init__()函數為對象的初始化操作提供了很大的自由度,對于不可變(每次操作都會産生一個新執行個體)的對象而言,聲明和定義是非常重要的。在第1章中,我們會讨論一些關于這個函數設計的方案。

__init__()方法的重要性展現在兩點。首先,初始化既是對象生命周期的開始,也是非常重要的一個步驟,每個對象都必須正确地執行了初始化才能夠正常地工作。其次,__init()__方法的參數可以多種形式來完成指派。

因為__init()__方法傳參方式的多樣化,意味着對象的初始化過程也會有多種。關于這一點我們将使用一些有代表性的例子對此進行詳細說明。

在深入讨論__init__()函數之前,需要看一下python語言的類層次結構。簡單地說,所有的類都可以繼承object類,在自定義類中可以提供比較操作的預設實作。

本章會示範簡單對象初始化的不同形式(例如,打牌)。随後将深入探讨複雜對象的初始化過程,涉及集合以及使用政策和狀态模式實作的玩家類。

每個python類的定義都會隐式繼承自object類,它的定義非常簡單,幾乎什麼行為都不包括。我們可以建立一個object執行個體,但很多事情無法完成,因為很多特殊方法的調用程式都會抛出異常。

對于任何自定義類,都會隐式繼承object。以下是一個類定義的示例(隐式繼承了object類)。

下面是對自定義類進行互動的代碼。

可以看到類定義就是對type類的一個對象的類型聲明,基類為object。

相應地,派生自object類中的對象方法也将繼承各自相應的預設實作。在某些情況下,基類中一些特殊方法的預設行為也正是我們想要的。對于一些特殊情況,就需要重寫這些方法。