初学者:Python值错误:int()的无效文字
我正在用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 个回答
rank1 = Card.Card.getRank(card1)
看起来你是在尝试把 getRank
当作静态方法来调用。其实,getRank 需要一个它自己的实例作为第一个参数。通常这意味着你应该有一个 Card 对象,但你上面调用的方式并没有传递这样的对象。我真惊讶它居然允许你这样调用。这样应该会报错,提示参数数量不对。
请发更多代码过来,但看起来你的设计上有一些很严重的基础问题。
更新:
这是什么情况?
RANK= ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]*FOUR
你为什么需要一个包含四个重复等级的列表呢?
你的代码看起来有点糟糕——缩进不规范,括号用得不必要(那些是字符串还是元组?),函数式编程和面向对象编程混在一起,还有静态方法调用非静态方法等等。
最初的问题是“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()
这一行写得不对:
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实例中导入同一个模块,它不会更新到最新的变化。而且,如果你重新定义了一个类,已经存在的实例仍然会使用旧的方法实现。