为何转换为字符串后Python仍触发TypeError?
问题描述
我为Blackjack游戏编写了Player和Dealer类,但在results函数中使用f-string打印时触发了TypeError:
print(f"{name}'s hand is {Player.hand}, total is {sum(Player.hand_val)}")
TypeError: unsupported operand type(s) for +: 'int' and 'str'
我尝试过用.format()和str()方法,还是出现相同错误,十分困惑。
附上相关代码:
import random as r class Player: wallet = 5000 hand_val = [] hand = [] def __init__(self, wallet, hand_val=None, hand=None): self.wallet = wallet self.hand_val = hand_val self.hand = hand class Dealer(Player): hand_val = [] hand = [] def __init__(self, hand_val, hand, wallet): super().__init__(hand_val, hand) self.hand_val = hand_val self.hand = hand def cardgenerate(): cards = [("A", 1), ("2", 2), ("3", 3), ("4", 4), ("5", 5), ("6", 6), ("7", 7), ("8", 8), ("9", 9), ("10", 10), ("J", 10), ("Q", 10), ("K", 10)] select = r.choice(cards) cardGen.append(select[0]) cardGen_value.append(select[1]) cardGen = [] cardGen_value = [] def hit(): for i in range(2): cardgenerate() # playerHand is from even indexes from cardGen[] Player.hand.append(cardGen[0]) Player.hand_val.append(cardGen[0]) # dealerHand is from odd indexes from cardGen[] Dealer.hand.append(cardGen[1]) Dealer.hand_val.append(cardGen[1]) def stay(): cardgenerate() Dealer.hand.append(cardGen[0]) Dealer.hand_val.append(cardGen[0]) def pcheck_lose(): if sum(Player.hand_val) > 21: print("BUST!!! You lost") Player.hand_val = [] return True def dcheck_lose(): if sum(cardGen_value) > 21: print("THE DEALER BUSTED!!! You won") Dealer.hand_val = [] return True def results(): name = "Player" # 补充缺失的name变量示例 print(f"{name}'s hand is {Player.hand}, total is {sum(Player.hand_val)}") print(f"Dealer's hand is {Dealer.hand}, total is {sum(Dealer.hand_val)}")
错误原因
报错的核心是你往Player.hand_val和Dealer.hand_val中存入的是卡片的字符串标识(如"A"、"10"),而非对应的数值:
- 在
hit()和stay()函数里,你调用Player.hand_val.append(cardGen[0]),但cardGen[0]是卡片的符号(字符串类型),不是cardgenerate()生成的数值(存在cardGen_value里) - 当执行
sum(Player.hand_val)时,sum会尝试对列表元素求和,但字符串和整数无法相加,直接触发TypeError
另外还有两个关键问题:
- 直接操作类属性(如
Player.hand)而非实例属性,会导致所有玩家/庄家共享同一手牌,逻辑混乱 Dealer的__init__方法调用父类时参数顺序错误,父类Player的__init__参数顺序是(wallet, hand_val, hand),但你传成了(hand_val, hand),会导致钱包赋值错误
修复方案
1. 修正hand_val的赋值逻辑
把卡片数值存入hand_val,而非符号:
def hit(): cardGen.clear() cardGen_value.clear() for i in range(2): cardgenerate() # 玩家存符号到hand,数值到hand_val Player.hand.append(cardGen[0]) Player.hand_val.append(cardGen_value[0]) # 庄家存符号到hand,数值到hand_val Dealer.hand.append(cardGen[1]) Dealer.hand_val.append(cardGen_value[1]) def stay(): cardGen.clear() cardGen_value.clear() cardgenerate() Dealer.hand.append(cardGen[0]) Dealer.hand_val.append(cardGen_value[0])
2. 改用实例属性操作
创建Player和Dealer的实例,避免类属性共享问题:
# 初始化实例 player = Player(wallet=5000, hand_val=[], hand=[]) dealer = Dealer(wallet=0, hand_val=[], hand=[]) # 庄家钱包按需设置
之后所有函数里的Player.hand替换为player.hand,Dealer.hand_val替换为dealer.hand_val,以此类推。
3. 修正Dealer的__init__参数顺序
class Dealer(Player): def __init__(self, wallet, hand_val=None, hand=None): super().__init__(wallet, hand_val, hand)
4. 修正dcheck_lose函数逻辑
用庄家的hand_val求和,而非全局的cardGen_value:
def dcheck_lose(): if sum(dealer.hand_val) > 21: print("THE DEALER BUSTED!!! You won") dealer.hand_val.clear() dealer.hand.clear() return True
内容的提问来源于stack exchange,提问作者keqae
相关产品推荐
相关产品推荐

