初学者:Python值错误:int()的无效文字

3 投票
5 回答
6674 浏览
提问于 2025-04-16 08:26

我正在用Python做一个简单的黑杰克程序,但遇到了一个错误:“ValueError: invalid literal for int() with base 10: ...”。为了计算玩家手牌的总值,在创建了卡片对象后,我试图获取这张卡片的点数:

rank1 = Card.Card.getRank(card1)

这是类的方法:

 def getRank(self):
      if self.__rank == ('J'):
          self.__rank = 10
          return self.__rank
      elif self.__rank == ('Q'):
          self.__rank = 10
          return self.__rank
      elif self.__rank ==  ('K'):
          self.__rank = 10
          return self.__rank
      elif self.__rank == ('A'):
          self.__rank = 11
          return self.__rank
      else:
          self.__rank = self.__rank
          return int(self.__rank)`

只有在点数是'Q'或'K'时,它才会返回这个错误,而'J'返回10,'A'返回11。我不明白为什么'Q'和'K'会出错,因为'J'和'A'的代码是一样的……希望能得到一些帮助……如果有用的话,在这之前我有:

这是整个类的代码

#Card class

#Class card holds ranks and suits of deck
#

TEN = 10
FOUR = 4

class Card():
     #Create rank list
     RANK= ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]*FOUR


     #Create list with rank names
     rankNames=[None, 'Ace', 'Two', 'Three', 'Four', 'Five', 'Six', 
                'Seven', 'Eight', 'Nine', 'Ten', 'Jack', 'Queen', 'King']


     #Create suit list
     suitNames = ['CLUBS','DIAMONDS', 'HEARTS', 'SPADES']


     #Takes in rank, suit to create a deck of cards
     def __init__(self, rank, suit):
          self.__rank = rank
          self.__suit = suit


     #Returns the rank of card
     def getRank(self):
          if self.__rank == ('J'):
              print (repr(self.__rank))
              self.__rank = 10
              return self.__rank
          elif self.__rank == ('Q'):
              self.__rank = 10
              print (repr(self.__rank))
              return self.__rank
          elif self.__rank ==  ('K'):
              print (repr(self.__rank))
              self.__rank = 10
              return self.__rank
          elif self.__rank == ('A'):
              print (repr(self.__rank))
              self.__rank = 11
              return self.__rank
          else:
              self.rank = self.__rank
              print (repr(self.__rank))
              return int(self.__rank)   


     #Returns suit of card
     def getSuit(self):
          return self.__suit


     #Returns number of points the card is worth
     def BJVaue(self):
          if self.rank < 10:
               return self.rank
          else:
               return TEN


     def __str__(self):
          return "%s of %s" % ([self.__rank], [self.__suit])

这是我创建卡片对象的地方

#Create a player hand                
player = []    
#Draw two cards for player add append
player.append(drawCard())
player.append(drawCard())

#Display players cards
print ("You currently have:\n" , player)

#Get the rank of the card
card1 = player[0]
card2 = player[1]

#Update players card status
print (card1)
print (card2)

#Get the total of the hand
rank1 = Card.Card.getRank(card1)
rank2 = Card.Card.getRank(card2)

#Get the ranks of players cards
playerRank = [rank1 , rank2]

#Get total of players hand
totalPlayer = getTotal(playerRank)

#Display players total
print ("Your current total is: ", totalPlayer)

这是计算总值的函数

def getTotal(rank):
    #Create and set accumulator to 0
    total = 0

    #for each value in the rank
    for value in rank:
        #add to total
        total += value

    #Return total
    return total

希望这能帮到你

5 个回答

0
rank1 = Card.Card.getRank(card1)

看起来你是在尝试把 getRank 当作静态方法来调用。其实,getRank 需要一个它自己的实例作为第一个参数。通常这意味着你应该有一个 Card 对象,但你上面调用的方式并没有传递这样的对象。我真惊讶它居然允许你这样调用。这样应该会报错,提示参数数量不对。

请发更多代码过来,但看起来你的设计上有一些很严重的基础问题。

更新

这是什么情况?

RANK= ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]*FOUR

你为什么需要一个包含四个重复等级的列表呢?

1

你的代码看起来有点糟糕——缩进不规范,括号用得不必要(那些是字符串还是元组?),函数式编程和面向对象编程混在一起,还有静态方法调用非静态方法等等。

最初的问题是“ValueError: invalid literal for int() with base 10: ...”,这意味着你传给int()的值,它不知道怎么把这个值转换成整数。那么问题来了:这个值是什么?它是从哪里来的呢?

试着替换一下

    VALUE = {
        '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, '10':10,
        'J':10, 'Q':10, 'K':10, 'A':11
    }
    def getValue(self):
        try:
            return Card.VALUE[self.__rank]
        except KeyError:
            print "%s is not a valid rank" % (self.__rank)

看看会得到什么。我猜测是drawCard生成的等级值,Card.getValue不知道该怎么处理。

你的代码还有其他问题:

TEN = 10
FOUR = 4

使用定义好的值的目的就是为了提供语义意义,并且方便修改;然而,FOUR和4在上下文中没有什么区别,我看不出改变FOUR或TEN的值有什么意义(实际上,如果FOUR等于3,那就会让理解你的代码变得更加困难)。试着把它们改名为FACECARD_VALUE和NUMBER_OF_SUITS。

你在使用“rank”这个词时,指代了不同的意思:一方面是表示牌的字符,另一方面是牌在你手中的价值。这会增加混淆;试着用face表示一种,用value表示另一种吧!

你似乎把drawCard()当作一个独立的函数在用;那你是怎么跟踪已经发出的牌的呢?比如说,发出两张黑桃A,这样合理吗?我建议你创建一个Deck对象,初始化52张标准牌,洗牌后,deck.getCard()从列表中返回一张牌,而不是随机生成。

看看你对以下内容的看法:

import random

class Deck():
    def __init__(self):
        self.cards = [Card(f,s) for f in Card.FACE for s in Card.SUIT]
        self.shuffle()

    def shuffle(self):
        random.shuffle(self.cards)

    def getCard(self):
        return self.cards.pop()

class Card():
    # Class static data
    FACE = ('A',   '2',   '3',     '4',    '5',    '6',   '7',     '8',     '9',    '10',  'J',    'Q',     'K')
    NAME = ('Ace', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Jack', 'Queen', 'King')
    RANK = (11,    2,     3,       4,      5,      6,     7,       8,       9,      10,    10,     10,      10)
    SUIT = ('Clubs','Diamonds', 'Hearts', 'Spades')

    def __init__(self, face, suit):
        ind = Card.FACE.index(face)
        self.__face = Card.FACE[ind]   # the long way around, but keeps it consistent
        self.__name = Card.NAME[ind]
        self.__rank = Card.RANK[ind]

        ind = Card.SUIT.index(suit)
        self.__suit = Card.SUIT[ind]

    def getFace(self):
        return self.__face

    def getName(self):
        return self.__name

    def getRank(self):
        return self.__rank

    def getSuit(self):
        return self.__suit

    def __str__(self):
        return "%s of %s" % (self.__name, self.__suit)

    def __repr__(self):
        return "%s%s" % (self.__face, self.__suit[:1])

class Player():
    def __init__(self):
        self.cards = []

    def drawCard(self, deck):
        self.cards.append(deck.getCard())

    def drawCards(self, deck, num=2):
        for i in range(num):
            self.drawCard(deck)

    def getRank(self):
        return sum( c.getRank() for c in self.cards )

    def __str__(self):
        cards = ', '.join(str(c) for c in self.cards)
        return  "%s: %d" % (cards, self.getRank())

    def __repr__(self):
        return ' '.join([repr(c) for c in self.cards])

class Game():
    def __init__(self):
        self.deck = Deck()
        self.player1 = Player()
        self.player2 = Player()

    def test(self):
        self.player1.drawCards(self.deck, 2)
        print "Player 1:", self.player1

        self.player2.drawCards(self.deck, 2)
        print "Player 2:", self.player2

def main():
    g = Game()
    g.test()

if __name__=="__main__":
    main()
3

这一行写得不对:

  if self.__rank == ('J' or 'Q' or 'K'):

('J' or 'Q' or 'K') 这个表达式的结果是 'J',所以这一行实际上只是在检查 self.__rank == 'J'

你其实想要的是:

  if self.__rank in ('J', 'Q', 'K'):

我觉得你第一个代码示例应该是可以工作的。你确定你真的在运行新代码吗?如果你尝试在一个正在运行的Python实例中导入同一个模块,它不会更新到最新的变化。而且,如果你重新定义了一个类,已经存在的实例仍然会使用旧的方法实现。

撰写回答