簡體   English   中英

如何在Python中調試OOP類/方法

[英]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張牌:)此外,將intstr作為排名將會很難尷尬:當然你會想要比較排名,這種表現會打擊你。 (解決方案:存儲僅作為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM