You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何转换为字符串后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

另外还有两个关键问题:

  1. 直接操作类属性(如Player.hand)而非实例属性,会导致所有玩家/庄家共享同一手牌,逻辑混乱
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 19:45:56