[時間割:Python]『みんなのPython』その6
2008/09/26 02:31 posted by kunkichi
はい、木曜は『Python』です。
先週はちょっとさぼってしまいましたが、実は前にも『はじめてのPython』の時にもあった「リファレンス」がやっぱりちょっとわかりにくかったので、まとめきれませんでした。
ということで、今週もう一度読み直してみたので、まとめてみます。
- Pythonは参照渡しが基本。なので変数はオブジェクト(実体)と結びついている。
- ただし数値、文字列などの「書き換え不能」なオブジェクトの場合は値渡し。 つまり、リスト、辞書などの「書き換え可能」なオブジェクトはリファレンスとなるので、オブジェクトを呼び出すようなメソッドを使うと、元の変数も変わってしまうので注意。
>>> a=[1,2,3,4]
>>> b=a
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3, 4]
>>> a.append(5)
>>> a
[1, 2, 3, 4, 5]
>>> b
[1, 2, 3, 4, 5] - これを回避するためには、リストをリテラルで代入するか、リストのコピーを代入する。
>>> a=[1,2,3,4]リストのコピーを作るにはスライスを使う。
>>> b=[1,2,3,4]
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3, 4]
>>> a.append(5)
>>> a
[1, 2, 3, 4, 5]
>>> b
[1, 2, 3, 4]>>> a=[1,2,3,4]辞書の場合はスライスは使えないのでcopyモジュールを使う。
>>> b=a[:]
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3, 4]
>>> a.append(5)
>>> a
[1, 2, 3, 4, 5]
>>> b
[1, 2, 3, 4]>>> a={1:"one",2:"two",3:"three"}
>>> import copy
>>> b=copy.copy(a)
>>> a
{1: 'one', 2: 'two', 3: 'three'}
>>> b
{1: 'one', 2: 'two', 3: 'three'}
>>> a[4]="four"
>>> a
{1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>>> b
{1: 'one', 2: 'two', 3: 'three'} - copy関数は「浅い」コピー。多次元配列とか書き換え可能なオブジェクトを含む辞書などは「深い」コピー、deepcopy関数を使う。
- 書き換え可能なオブジェクトを関数の引数として渡して関数内でそれを変更すると、関数の外でもオブジェクトが書き換えられるので注意。
>>> def add_str(list):
... list.append('added!')
...
>>> a=[1,2,3,4]
>>> add_str(a)
>>> a
[1, 2, 3, 4, 'added!'] - 関数の引数デフォルト値に書き換え可能なオブジェクトを指定して関数内でそれを変更しても、デフォルト値の代入は1回しか行われないので注意。関数内の変更だけが繰り返される。
>>> def add_str(list=[1,2,3]):
... list.append('added!')
... print list
...
>>> add_str()
[1, 2, 3, 'added!']
>>> add_str()
[1, 2, 3, 'added!', 'added!']
>>> add_str()
[1, 2, 3, 'added!', 'added!', 'added!']
>>> add_str([1,2,3])
[1, 2, 3, 'added!']
>>> add_str([1,2,3])
[1, 2, 3, 'added!']
>>> add_str([1,2,3])
[1, 2, 3, 'added!']
>>> add_str()
[1, 2, 3, 'added!', 'added!', 'added!', 'added!']
うーん、Perlでも参照渡しとか普通に使うし、Cで言うポインタも最近仕組みがわかってきたので意味は理解できるんやけど、やっぱりちょっと考えないとサッとイメージできないなぁ。ポインタが鬼門と言われるわけだ。
ちょこちょこスクリプト書いて体で覚えないとね。






コメント&トラックバック
トラックバックURL: