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」内で、辞書 A には localDict の内容が含まれます。しかし、「foo」の範囲外では、辞書 A は空です。一方、キーと値が割り当てられた後、辞書 B は関数「foo」から出た後も値を保持します。

関数「foo」の外でcopy.deepcopy()がコピーする値を維持するにはどうすればよいですか?

4

3 に答える 3

1

次のことを考えてみてください。

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

内部fooでは、d = {1: 2}いくつかのオブジェクトを name にバインドしますddこの名前はローカルであり、指すために使用されるオブジェクトを変更しません。一方で:

>>> 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可能な変数を変更しているためです。必要な動作を取得するための 2 つのオプションを次に示します。

  • を使用する代わりに、次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 と呼ばれる新しい dict があり、グローバル スコープの外側の A とはまったく関係がなく、関数が終了するとガベージ コレクションが行われるため、実際には何も起こらず、「me」キーだけが B に追加されます。

代わりに:

A = copy.deepcopy(localDict)

このようなことをすると、期待どおりに機能します。

C = copy.deepcopy(localDict)

A.update(C)

しかし、あなたが本当に欲しいのは copy モジュールとは何の関係もないようで、次のようになります:

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 に答える