天天看點

《Python面向對象程式設計指南》——1.10 一些其他的類定義

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

正如前面所提到的,玩家有兩種政策:下注和打牌。每個player執行個體會和模拟器進行很多互動。我們這裡把這個模拟器命名為table類。

table類的職責需要配合player執行個體完成以下事件。

玩家必須基于玩牌政策初始化一個牌局。

随後玩家會得到一手牌。

如果手中的牌是可以拆分的,玩家需要在基于目前玩法的情況下決定是否分牌。這會建立新的hand對象。在一些場合中,新分出去的牌是可以再分的。

對于每個hand執行個體,玩家必須基于目前玩法決定叫牌、雙倍還是停叫。

然後玩家會收到賬單,他們可以根據輸赢情況來決定之後的遊戲政策。

基于以上需求,我們可以看出table類需要提供一些api函數來擷取牌局、建立hand對象、分牌、提供單手和多手政策以及支付,這個對象的職責很多,用于追蹤與players集合所有相關操作的狀态。

以下是table類中投注和牌的邏輯處理的相關代碼。

table類會被player類調用,進而接受牌局、建立hand對象,然後決定手中的牌是否為保險下注。此外,還需要提供一些可以被player類用來擷取牌和支付的函數。

在get_hand()函數中的異常處理部分,并沒有準确的模拟玩牌時的真實場景。這可能會導緻統計不正确。更好的模拟方式是,在牌用盡的情況下需要建立一副牌并洗牌,而不是抛出異常。

為了更适當地互動設計并模拟真實的遊戲場景,player類需要一個下注政策。下注政策是一個狀态對象,它決定了初始的下注級别,通常當每局遊戲輸赢之後可以再次選擇不同的下注政策。

理想情況下,希望有多個下注政策對象。python中有一個子產品包含了很多裝飾器,可以用來建立抽象基類。一種非正式的建立政策對象的方式是在基類函數中抛出異常,用以辨別一些方法必須在子類中提供實作。

以下代碼包含了一個抽象基類和一個子類,用來定義一種下注政策。

基類中定義了帶有預設傳回值的方法。抽象基類中的bet()方法抛出異常,子類必須給出 bet()方法的實作。其他方法可以選擇是否使用基類的預設實作。前面給出的遊戲政策加上這個下注政策,可以模拟出play類中更複雜的__init__()函數的使用場景。

我們可以使用abc子產品來豐富抽象基類的實作,如以下代碼段所示。

它有兩個好處:首先,它阻止了對抽象基類bettingstrategy2的執行個體化,其次任何沒有提供bet()方法實作的子類也是不能被執行個體化的。如果我們試圖建立一個類的執行個體,而這個類并沒有提供抽象方法的實作,程式就會抛出一個異常。

當然,如果基類的抽象方法提供了實作,那麼就是合法的,而且可以通過super().bet()來調用。