Search code examples
pythonappendattributeerror

Python, .append() and an AttributeError


I am trying to write a blackjack program, but when I try to send a message from my deck object to another object that uses .append(), I keep getting an AttributeError: object has no 'append'

Here's what code I think is relevant:

class Deck(Hand):

    def deal(self, players, per_hand= 1):
        for rounds in range(per_hand):
            for hand in players:
                if self.hand:
                    top_card = self.hand[0]
                    self.give(top_card,hand)

The players parameter is a tuple of objects I instantiated using:

class Bj_player(Player,Hand):

    def __init__(self,name,score= 0,status= None):
        self.name = name
        self.score = score
        self.status = status
        self.hand = Hand()

the Player base class has nothing in it but a few inputs from the user. Is the above where I'm getting it wrong?

class Hand(object):
"""a hand of cards"""


    def __init__(self):
        self.hand = []

    def add(self, card):
        self.hand.append(card)


    def give(self,card,other_hand):
        if self.hand:
            self.hand.remove(card)
            other_hand.add(card)
        else:
            print("EMPTY ALREADY. COULD NOT GIVE")

I took out the str part to cut it down. The error I'm getting is this:

 line 44, in add
    self.hand.append(card)
    AttributeError: 'Hand' object has no attribute 'append'

I'm pretty new so the more simply explained the better. Thanks.

Also, just in case it's helpful, here's how I'm starting things out:

deck = Deck() #populated and all that other stuff

total_players = Player.ask_number("How many players will there be? (1-6): ",1,6)
for player in range(total_players):
    name = input("What is the player's name? ")
    x = Bj_player(name)
    roster.append(x)

deck.deal(roster,2) #error =(

Solution

  • The problem is the line:

            self.hand = Hand()
    

    within the Bj_player class. That makes the self.hand variable a Hand instance, rather than a list as it should be. roster is a list of these BJ_player instances, so when you call deck.deal(roster), and within the function it says for hand in players, each hand object will be one of these Bj_player instances.

    The best way to solve this is for Bj_player not to inherit from hand. (Indeed, it's not clear why you have it inherit from Player, or what useful functionality the Player class provides). Instead, have Bj_player be its own class (perhaps named Player instead- less confusing) and change the line

        for hand in players:
            if self.hand:
                top_card = self.hand[0]
                self.give(top_card,hand)
    

    to

        for player in players:
            if self.hand:
                top_card = self.hand[0]
                self.give(top_card,player.hand)
    

    A separate note: if you changed self.hand to self.cards, it would make things a lot clearer!