[英]How to debug OOP Class/Method in Python
我正在嘗試建立程序來模擬紙牌游戲的規范教學編程練習。 這是我有多遠:
class Card:
def __init__(self, suit, rank):
self.suit = suit
self.rank = rank
self.card = str(self.suit) + " " + str(self.rank)
class Deck:
def __init__(self):
self.deck = []
def Deck_Maker(self):
ranks = range(1, 11) + ["J", "Q", "K", "A"]
suits = ["Club", "Heart", "Spade", "Diamond"]
return self.deck.append(Card(suits[0], ranks[0]))
顯然我還沒有完成,我必須循環穿上套裝和等級來構建套牌。 但是,在繼續之前,我想檢查一下我是否正常。 為此,我想在調用Deck_Maker方法后打印結果。 我嘗試使用以下代碼執行此操作...
def __str__(self):
d = self.deck
d2 = d.Deck_Maker()
return str(d2)
不幸的是, print(Deck().Deck_Maker())
返回None
。
我究竟做錯了什么? 更一般地說,程序員在創建類和方法時如何在類和方法中進行討論?
謝謝!
列表中的append方法返回None,因此這是預期的。 嘗試拆分你的線:
deck = Deck()
deck.Deck_Maker()
print(deck)
或者將方法Deck_Maker更改為:
def Deck_Maker(self):
ranks = range(1, 11) + ["J", "Q", "K", "A"]
suits = ["Club", "Heart", "Spade", "Diamond"]
self.deck.append(Card(suits[0], ranks[0]))
return self
編輯:你的str方法也有問題。 當您將d設置為self.deck時,您將其設置為列表。 該列表對Deck_Maker方法一無所知。 嘗試更改為以下方法。 這會將您的列表變成一個字符串。 為了使其更具可讀性,您可能還需要在卡類中添加str方法。
def __str__(self):
return str(self.deck)
一些建議:
對Card
一個更改我建議:不要在__init__
初始化屬性card
,而是從__init__
刪除最后一行並添加__str__
方法:
class Card():
def __init__(self, suit, rank):
self.suit = suit
self.rank = rank
def __str__(self):
return str(self.suit) + " " + str(self.rank)
現在每張Card
知道如何將自己表現為一個按需str
。 除了__str__
之外,您可以添加__repr__
方法:
def __repr__(self):
return 'Card(%s, %s)' % (self.suit, self.rank)
Deck
課
您還可以向Deck
類添加__str__
方法。
我已經將Deck_Maker
方法重命名為make_Deck
,並且我已經使它成為類方法,因為名稱表明它意味着它是一個“工廠方法”,可以在Deck
類而不是Deck
實例上調用。 該方法現在需要返回它創建的Deck
。
我還將deck
成員變量重命名為cards
,因為畢竟它是卡片列表,我們將要使用deck
來引用deck
:)
最后,我根據最終其他一些方法想要使用它們的理論,制作了套裝列表並對類屬性進行了排名,而不是make_Deck
。 在Python 3中, range
返回一個可迭代的,因此它周圍的list()
。
幾個問題:我不確定1級的牌是什么,因為你有"A"
; 2到11似乎更有可能。 (因此, Deck
目前擁有56張牌:)此外,將int
和str
作為排名將會很難尷尬:當然你會想要比較排名,這種表現會打擊你。 (解決方案:存儲僅作為int
存儲,並在__str__
和__repr__
方法中轉換。)您可能希望等級比較為Card方法。 在這種情況下, _ranks
和_suits
應該可以訪問該類(例如,module-globals)。
但這些排名和適合問題是另一天,我將保持定義基本不變。
class Deck():
_ranks = list(range(1, 11)) + ["J", "Q", "K", "A"]
_suits = ["Club", "Heart", "Spade", "Diamond"]
def __init__(self):
self.cards = []
@classmethod
def make_Deck(cls):
"""cls is Deck"""
deck = cls() # make a Deck
for s in cls._suits:
for r in cls._ranks:
deck.cards.append(Card(s, r))
return deck
# A basic example:
def __str__(self):
return ', '.join([str(card) for card in self.cards])
現在您可以使用以下代碼:
>>> deck = Deck.make_Deck()
>>> print(deck) # calls deck.__str__
它打印了deck
中所有56(!)卡的str
表示,以逗號分隔並且全部在一行上:
Club 1, Club 2, Club 3, Club 4, Club 5, Club 6, Club 7, Club 8, Club 9, Club 10, Club J, Club Q, Club K, Club A, Heart 1, Heart 2, Heart 3, Heart 4, Heart 5, Heart 6, Heart 7, Heart 8, Heart 9, Heart 10, Heart J, Heart Q, Heart K, Heart A, Spade 1, Spade 2, Spade 3, Spade 4, Spade 5, Spade 6, Spade 7, Spade 8, Spade 9, Spade 10, Spade J, Spade Q, Spade K, Spade A, Diamond 1, Diamond 2, Diamond 3, Diamond 4, Diamond 5, Diamond 6, Diamond 7, Diamond 8, Diamond 9, Diamond 10, Diamond J, Diamond Q, Diamond K, Diamond A
我知道這聽起來不是很聰明,但是有一個很好的debuger,有斷點,有幫助。 您實際上可以看到執行流程。
棘手的問題是mro(沿着繼承鏈的方法解析順序),類方法(結果來自實例/類)和元類(創建具有類型的類的類)。 要理解這些問題,初始化以及提供結果的對象,請在每個init中刪除日志記錄或print語句,並在方法中刪除“從對象baz輸入方法foo”。 這將使事情更清楚。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.