- 1. 概要
- 2. オブジェクトコピー
1. 概要
わたしは、「FORTRAN」で生まれて、「C」で育ったのである。
基本、「FORTRAN」は、関数に渡す引数は、すべてアドレスで渡るようなもんだと理解してもらいたい。
「C 言語」で、値で渡すのが基本で、アドレスを渡すのには、作法が必要なので、苦労したものです。
そうして育ってきたわたしが、この手の言語には、苦労するのである。
本ページは、下記のサイトを参考にさせていただきました(「perl」のページもあるのだ)。
「配列 | Perl、配列の初期化と要素の出し入れ」
「copy – オブジェクトのコピー - Python Module of the Week」
コンパイル・リンクするのが面倒なので、「perl」を使います。
my @a1 = ( 'one', 'two', 'three', 'four' );
my @a2 = @a1;
$,=', ';
print(@a1);
print("\n");
print(@a2);
print("\n");
@a1[2] = 'three-cahnge';
print(@a1);
print("\n");
print(@a2);
print("\n");
てなソースを書いて、実行すると、下記の結果が得られます。
one, two, three, four
one, two, three, four
one, two, three-cahnge, four
one, two, three, four
「@a2」に「@a1」を代入した後で、「@a1」の内容を書き換えても、「@a2」にはなんら、影響を与えない。
「C 言語」や「perl」にとっては、何の変哲もない、ごく普通の動きです。
ところが、「python」で下記のようなソースを書いて
l1 = [ 'one', 'two', 'three', 'four' ]
l2 = l1
print(l1)
print(l2)
l1[2] = 'three-cahnge'
print(l1)
print(l2)
こいつを実行すると
['one', 'two', 'three', 'four']
['one', 'two', 'three', 'four']
['one', 'two', 'three-cahnge', 'four']
['one', 'two', 'three-cahnge', 'four']
やや、なんだこれは!ってことになるのだ。
代入は、単なる代入でなく、実体(?)まで渡っちゃうので、「l2」に「l1」を代入した後に変更した「l1」の内容は、「l2」にまで反映されちゃうのである。
2. オブジェクトコピー
前項の状態を回避するには、モジュールをインポートして、メソッドを使用しなければならないのだ。
すなわち、下記のようなソースを書いて
import copy
l1 = [ 'one', 'two', 'three', 'four' ]
l2 = copy.deepcopy(l1)
print(l1)
print(l2)
l1[2] = 'three-cahnge'
print(l1)
print(l2)
実行すれば、下記のような結果になるのである。
['one', 'two', 'three', 'four']
['one', 'two', 'three', 'four']
['one', 'two', 'three-cahnge', 'four']
['one', 'two', 'three', 'four']
わたしのような素人は、四の五の言わず、「deepcopy」を使うに限る。
|