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

Python字典作为函数参数时原模板字典被意外修改的问题咨询

Python字典传参后原字典被修改的问题解决

问题描述

我用初始字典做模板,按以下流程操作:

  1. 创建初始模板字典;
  2. 把字典传入函数,在函数内赋值给新变量操作;
  3. 向字典添加元素后返回给主代码的新变量;
  4. 重复步骤处理另一个变量,每次复用这个模板字典。

但实际运行时,初始模板字典也被同步更新,导致第二次传入时带着之前的脏数据。另外我原本以为全局的startDeck能被函数访问,但Python提示找不到它,而且所有字典(包括函数内临时字典)内容完全一样,搞不懂原因。

我的最小示例代码:

startDeck = {
  "deckSize":0,
  "score":0,
  "blackjack":False,
}


def playBlackjack(deck):
  userDeck = dealCards(cards= deck,count=2)
  compDeck = dealCards(cards= deck,count=1)

def dealCards(cards,count):
  
  score = cards["score"]
  deckSize = cards["deckSize"]
  
  for n in range(count):
    newCard = {}
    deckSize+=1
    score+=1
    cardNo = "card" + str(deckSize)

    newCard["card"] = "hearts"
    newCard["value"] = 10
    newCard["suit"] = "clubs"
    cards[cardNo]=newCard

  cards["score"]=score
  cards["deckSize"]=deckSize

  return cards


playBlackjack(startDeck)

核心原因

Python里字典是可变对象,函数传参时传递的是对象的内存引用,不是创建新的副本。所以你在dealCards函数里修改cards字典的内容,本质上就是直接修改原字典(也就是startDeck)的内存数据——不管你有没有返回这个字典,原模板都会被改变。

至于“全局字典找不到”的问题,看你提供的代码是通过参数传递startDeck的,这种情况不会出现找不到的问题。如果你的实际代码是直接在函数里引用startDeck却没传参,那需要注意:如果要修改全局变量,必须在函数开头加global startDeck声明,否则Python会把它当成局部变量,抛出未定义的错误。

解决方法:传入字典的副本

要避免修改原模板字典,每次传入函数时,都要创建一个字典的拷贝,分两种情况:

  • 浅拷贝:如果字典里没有嵌套的可变对象(比如你的startDeck里都是数字、布尔值,没有嵌套字典/列表),用dict.copy()或者{**startDeck}即可。
  • 深拷贝:如果字典里有嵌套的可变对象(比如某个键对应的值是另一个字典),需要用copy.deepcopy(),前提是先导入copy模块。

修改后的示例代码

# 如果用深拷贝需要导入copy模块,浅拷贝不需要
import copy

startDeck = {
  "deckSize":0,
  "score":0,
  "blackjack":False,
}


def playBlackjack(deck):
  # 传入浅拷贝的副本,避免修改原字典
  userDeck = dealCards(cards= deck.copy(), count=2)
  # 或者用深拷贝:copy.deepcopy(deck)
  compDeck = dealCards(cards= deck.copy(), count=1)

def dealCards(cards,count):
  
  score = cards["score"]
  deckSize = cards["deckSize"]
  
  for n in range(count):
    newCard = {}
    deckSize+=1
    score+=1
    cardNo = "card" + str(deckSize)

    newCard["card"] = "hearts"
    newCard["value"] = 10
    newCard["suit"] = "clubs"
    cards[cardNo]=newCard

  cards["score"]=score
  cards["deckSize"]=deckSize

  return cards


playBlackjack(startDeck)
# 此时startDeck仍然是初始状态,不会被修改

内容的提问来源于stack exchange,提问作者Otispunkmeyer86

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 23:03:09