Python関数パラメータ参照(転送/転送)/copy/deepcopy

5672 ワード

シン:
伝達値:変調された関数のローカル変数の変更は、プライマリ変調関数のローカル変数に影響しません.
≪アドレス|Address|emdw≫:変調された関数のローカル変数が変更されると、プライマリ・変調関数のローカル変数に影響します.
Pythonパラメータ伝達方式:伝達対象参照(伝達値と伝達先の混合方式)、数字、文字列、メタグループであれば伝達値;リストの場合、辞書はアドレスします.
copyシーンの使用:リストまたは辞書、内部要素が数値、文字列またはメタグループ
deepcopyシーンの使用:リストまたは辞書、内部要素にリストまたは辞書が含まれます
完全版:
1.送信値とアドレスの違い
値はパラメータを入力する値であり、アドレスはパラメータを入力するアドレス、すなわちメモリのアドレス(ポインタに相当)である.彼らの違いは,関数内で伝達されたパラメータに値を再付与すると,関数外のグローバル変数が相応に変化するかどうかであり,伝達値で伝達されたパラメータは変化せず,伝達アドレスで伝達されると変化する.
1 a=1
2 def f(b):
3     b=2
4 f(a)
5 print a

例えば、このコードでは、まずaの値が1であることを宣言し、aをパラメータとして関数fに入力し、関数fではbに対して2を再付与し、値を伝達する形式でaに入力すると、aの値は変わらず、依然として1であり、アドレスの形式(ただしこれはプログラマが決定できるものではない)でaに入力すると、aは2になる.これが伝達値と伝達先の違いです.
 
2.Pythonのアドレスと値はどうなっていますか?
Pythonでは、プログラマーが値を伝えるか、それともアドレスを伝えるかを選択することは許されません.Pythonパラメータ伝達は「伝達対象参照」方式を採用しているに違いない.実際、この方式は、値とアドレスの統合に相当する.
関数が辞書やリストなどの可変オブジェクトの参照を受け取ると、オブジェクトの元の値がアドレスに相当するように変更されます.関数が数値、文字、メタグループなどの可変オブジェクトの参照を受信した場合(オブジェクトアドレスでもあります!!)、元のオブジェクトを直接修正することはできません.値の伝達に相当します.
pythonの転送値と転送先は、転送パラメータのタイプに応じて選択されます.
値のパラメータタイプ:数値、文字列、メタグループ(immutable)
アドレスのパラメータタイプ:リスト、辞書(mutable)
1 a=1
2 def f(a):
3     a+=1
4 f(a)
5 print a

このコードの中で、aは数字のタイプなので、値を伝える方式で、aの値は変わらないで、出力は1になります
1 a=[1]
2 def f(a):
3     a[0]+=1
4 f(a)
5 print a

このコードでは,aのタイプがリストであるため,アドレスの形式であり,a[0]の値が変化して[2]に出力される.
3.copyとdeepcopy
関数だけでなく、関数の外の参照もこのルールに従います.
1 a=1
2 b=a
3 a=2
4 print a,b
5 a=[1]
6 b=a
7 a[0]=2
8 print a,b

1番目の出力は2,1、2番目の出力は[2]
b=a

したがってpythonでは、上記のコードを実行するとき、aが辞書またはリストであれば、プログラムが実行する操作は、b変数を新規に作成するのではなく、aの値をbにコピーするのではなく、b変数を新規に作成し、bの値をa、すなわちc言語に新しくaを指すポインタに相当する.したがって、aの値が変化すると、bの値はそれに応じて変化する.
しかし、aの値に等しいb変数を新規作成し、bの値がaの値に関連付けられていない場合、どうすればいいですか.このときcopyとdeepcopyを使います
 1 import copy
 2 
 3 a=[1,2,3]
 4 b=a
 5 a.append(4)
 6 print a,b
 7 
 8 a=[1,2,3]
 9 b=copy.copy(a)
10 a.append(4)
11 print a,b

上の出力は次のとおりです.
1 [1, 2, 3, 4] [1, 2, 3, 4]
2 [1, 2, 3, 4] [1, 2, 3]

ここではcopyを用いてbとaを等しくし,後でaの値を修正すればbの値は変わらない.copyはすでに私たちの上述の需要を実現することができるようですが、deepcopyは何の役に立ちますか?
もし私たちがこのような状況に遭遇したら、copyは解決できません.
1 a=[1,[1,2],3]
2 b=copy.copy(a)
3 a[1].append(4)
4 print a,b

ここで出力される結果は,[1,[1,2,4],3][1,[1,2,4],3]であり,このような結果は明らかに我々が望んでいるものではない.
リストまたは辞書パラメータの値がリストまたは辞書の場合、copyはパラメータのリストまたは辞書をコピーしません.deepcopyが使用されます.
1 a=[1,[1,2],3]
2 b=copy.deepcopy(a)
3 a[1].append(4)
4 print a,b

出力の結果は,[1,[1,2,4],3][1,[1,2],3]であった.
 
参考資料:http://www.cnblogs.com/Xjng/p/3829368.html