Domanda

I have built a class below with a constructor. The idea is that a PlayingCard object should be generated randomly by default if a rank and/or suit is not specified. In the event that an invalid suit or rank is specified, an object should not be created. I believe this is working, but I am not sure what to make of the exception. I wanted to verify that the only exception thrown in case of an invalid rank or suit is the one that I specified. I am confused why there is a 'NameError' that says the instance has no attribute 'suit' as I did not specify this when I wrote the raise statement.

Also, I would like to make the class flexible so that user defined rank and suit do not need to be passed in as strings when creating an instance, but I cannot seem to get it to work. If anybody could point me in the right direction or explain why I would not want to do this, it would be appreciated.

class PlayingCard:
    ranks = ['2','3','4','5','6','7','8','9','10','J','Q','K','A']
    suits = ['Spades', 'Hearts', 'Clubs', 'Diamonds']

    def __init__(self, rank = None, suit = None):
        if rank is None: self.rank = PlayingCard.ranks[rand.randint(0,12)]
        elif rank in PlayingCard.ranks: self.rank = rank


        if suit is None: self.suit = PlayingCard.suits[rand.randint(0,3)]
        elif suit in PlayingCard.suits: self.suit = suit


        if self.rank not in PlayingCard.ranks or self.suit not in PlayingCard.suits: raise NameError('Invalid Suit or Rank')


>>> c1 = PlayingCard('15','Diamonds')

Traceback (most recent call last):
  File "<pyshell#63>", line 1, in <module>
    c1 = PlayingCard('15','Diamonds')
  File "C:\Python27\poker.py", line 26, in __init__
    if self.rank not in PlayingCard.ranks or self.suit not in PlayingCard.suits: raise NameError('Invalid Suit or Rank')
AttributeError: PlayingCard instance has no attribute 'rank'

>>> c2 = PlayingCard('A', 'Swords')

Traceback (most recent call last):
  File "<pyshell#64>", line 1, in <module>
    c2 = PlayingCard('A', 'Swords')
  File "C:\Python27\poker.py", line 26, in __init__
    if self.rank not in PlayingCard.ranks or self.suit not in PlayingCard.suits: raise NameError('Invalid Suit or Rank')
AttributeError: PlayingCard instance has no attribute 'suit'
È stato utile?

Soluzione

When rank is not None and also not in ranks, self.rank is never set and so

if self.rank not in PlayingCard.ranks

won’t work; self.rank doesn’t exist. Same goes for suit. You could be more specific with the error and solve the problem all at once:

def __init__(self, rank = None, suit = None):
    if rank is None: self.rank = PlayingCard.ranks[rand.randint(0,12)]
    elif rank in PlayingCard.ranks: self.rank = rank
    else: raise NameError('Invalid rank')

    if suit is None: self.suit = PlayingCard.suits[rand.randint(0,3)]
    elif suit in PlayingCard.suits: self.suit = suit
    else: raise NameError('Invalid suit')
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top