2016-03-26 6 views
0

必要があるときに変更返さ:変数は、関数内で変更され、それは私が次のプログラム使用していない

def coordsRelToPoint(origin,point): 

    result = (int(origin[0]) - int(point[0]) , int(origin[1]) - int(point[1])) 

    return result 

def initCoordsRelToStartBattle(calibration): 
    print ('FUNCTION BEGIN') 
    print ('orig: %s' % str(calibration['center'])) 
    print ('') 
    new_calibration = {} 
    new_calibration = calibration 

    print ('orig: %s' % str(calibration['center'])) 
    print ('') 

    new_calibration['center'] = coordsRelToPoint((774,454),calibration['center']) 

    print ('orig: %s' % str(calibration['center'])) 
    print ('') 
    print ('new: %s' % str(new_calibration['center'])) 
    print ('') 
    print ('FUNCTION END')   
    return new_calibration 

def main(): 
    calibration = {} 
    calibration['center'] = (156,20) 
    initCoordsRelToStartBattle(calibration) 

if __name__ == "__main__": 
    main() 

それが画面上に次のように印刷されています。

FUNCTION BEGIN 
orig: (156, 20) 

orig: (156, 20) 

orig: (618, 434) 

new: (618, 434) 

FUNCTION END 

すると、私は理解していない何を私の元の変数が、別の関数で使われているために関数を呼び出すときに変更される理由です。

これは、関数から返されていなくても変数のキャリブレーションが変更されていることを意味するので、私はラインのorig((618、434)

答えて

0

問題は、既存の辞書を新しい変数に割り当てると、実際には新しい変数が同じオブジェクトを指しているということです。 id機能を使って、基本的にオブジェクトのアドレスを確認することができます。この例では、id(calibration)id(new_calibration)と同じアドレスが表示されます。新しい辞書が変更された場合でも元の辞書が変更されるのはそのためです。

実際に新しいコピーを取得するには、copyパッケージを使用し、deepcopy機能を使用することができます。あなたが変更する必要がありますライン、すなわち、new_calibrationの初期化です:

new_calibration = copy.deepcopy(calibration) 

、これは元の変数を保持することになります。

質問のコードでは、tupleが不変オブジェクトである辞書の要素であるため、シャローコピーも機能します。浅いコピーと深いコピーの違いは、基本的に最初のものが新しい複合オブジェクトを作成し、可能であればコピーされたオブジェクトに参照を追加し、後者は再帰的に新しいオブジェクトを作成することです。質問では、辞書内の各要素がタプルではなく2つの要素のリストであった場合、元の辞書のリストを保持しながらリストのただ1つの値を変更するには深いコピーが必要です。 浅いコピーと深いコピーの違いの詳細については、copyのドキュメントを参照してください。

+0

これはコピーではなく、浅いものでもありません。これは単に同じ*オブジェクトへの別の参照です。 –

+0

@DanielRosemanあなたが正しいです、私はエラーの説明を修正しました。ありがとう! – albertoql

0

はあなたのコードに次の文があります。

new_calibration = calibration 

これは、あなたがnew_calibrationを変更した場合、あなたはまた、変更はprint文に反映されている理由である、キャリブレーションを変更していることを意味します。

0

new_calibration = calibrationは、new_calibrationcalibrationが参照するのと同じオブジェクトを指すことを意味します。あなたがやろうとしているすべてのnew_calibrationを再定義である場合

new_calibration = calibration.copy() 

また、new_calibration = {}は無用です:あなたはコピーを作成したい場合は、dict.copy()メソッドを使用します。