0

我在使用 copy.copy() 和 copy.deepcopy() 以及 Python 的范围时遇到问题。我调用一个函数,一个字典作为参数传递。字典复制本地字典,但字典不保留复制的值。

def foo (A, B):
    localDict = {}
    localDict['name'] = "Simon"
    localDict['age'] = 55
    localDict['timestamp'] = "2011-05-13 15:13:22"
    localDict['phone'] = {'work':'555-123-1234', 'home':'555-771-2190', 'mobile':'213-601-9100'}

    A = copy.deepcopy(localDict)

    B['me'] = 'John Doe'
    return



def qua (A, B):
    print "qua(A): ", A
    print "qua(B): ", B

    return


# *** MAIN ***
# 
# Test
#
A = {}
B = {}

print "initial A: ", A
print "initial B: ", B

foo (A, B)

print "after foo(A): ", A
print "after foo(B): ", B

qua (A, B)

copy.deepcopy 有效,并且在函数“foo”中,dict A 具有 localDict 的内容。但是在“foo”的范围之外,dict A 是空的。同时,在分配了键和值后,dict B 保留了从函数 'foo' 出来后的值。

如何维护 copy.deepcopy() 在函数“foo”之外复制的值?

4

3 回答 3

1

想一想:

>>> def foo(d):
...   d = {1: 2}
... 
>>> d = {3: 4}
>>> d
{3: 4}
>>> foo(d)
>>> d
{3: 4}
>>> 

在里面food = {1: 2}将一些对象绑定到名称d。这个名字是本地的,它不会修改d用来指向的对象。另一方面:

>>> def bar(d):
...   d[1] = 2
... 
>>> bar(d)
>>> d
{1: 2, 3: 4}
>>> 

因此,这与您使用(深度)复制无关,这只是 Python 中“变量”的工作方式。

于 2012-04-21T03:21:30.387 回答
0

您看到的行为与 无关deepcopy(),您正在将名称重新分配给新值,除非您使用关键字A,否则该分配不会继续。global更改为B持久的原因是您正在修改一个可变变量,这里有两个选项可以让您获得所需的行为:

  • 而不是使用localDict,只需修改A

    def foo(A, B):
        A['name'] = "Simon"
        A['age'] = 55
        A['timestamp'] = "2011-05-13 15:13:22"
        A['phone'] = {'work':'555-123-1234', 'home':'555-771-2190', 'mobile':'213-601-9100'}
    
        B['me'] = 'John Doe'
        return
    
  • 使用A.update(copy.deepcopy(localDict))代替A = copy.deepcopy(localDict)

    def foo(A, B):
        localDict = {}
        localDict['name'] = "Simon"
        localDict['age'] = 55
        localDict['timestamp'] = "2011-05-13 15:13:22"
        localDict['phone'] = {'work':'555-123-1234', 'home':'555-771-2190', 'mobile':'213-601-9100'}
    
        A.update(copy.deepcopy(localDict))
    
        B['me'] = 'John Doe'
        return
    
于 2012-04-21T03:25:53.813 回答
0

发生的事情是,在 foo() 内部,您创建了 B 的副本并将其分配给 A,通过将新对象重新分配给相同的名称来隐藏您作为参数发送的空 dict。现在在函数内部你有一个名为 A 的新字典,在全局范围内与外部的 A 完全无关,并且当函数结束时它会被垃圾收集,所以实际上什么也没发生,只有添加到 B 的“me”键。

如果不是:

A = copy.deepcopy(localDict)

你做这样的事情,它会像你期望的那样工作:

C = copy.deepcopy(localDict)

A.update(C)

但似乎你真正想要的与复制模块无关,是这样的:

def foo (A, B):
    A['name'] = "Simon"
    A['age'] = 55
    A['timestamp'] = "2011-05-13 15:13:22"
    A['phone'] = {'work':'555-123-1234', 'home':'555-771-2190', 'mobile':'213-601-9100'}

    B['me'] = 'John Doe'
于 2012-04-21T03:21:18.253 回答