Python賦課メカニズム
5179 ワード
まず例を見てみましょう.
In [1]:
変数
単純なタイプ.
まず、このコードのPythonでの実行手順を見てみましょう.
Pythonには
Pythonは、変数
Pythonはこのとき
この手順を検証するには、
変数
In [2]:
Out[2]:
In [3]:
Out[3]:
In [4]:
Out[4]:
現在
In [5]:
Out[5]:
In [6]:
Out[6]:
Pythonは、表示される各オブジェクトに値が同じであっても値を割り当てます.たとえば、次のようにします.
In [7]:
Out[7]:
In [8]:
Out[8]:
In [9]:
Out[9]:
ただし、メモリの使用効率を向上させるために、数値の小さいintオブジェクトなどの簡単なオブジェクトに対して、Pythonはオブジェクトメモリを再利用する方法を採用しています.
In [10]:
Out[10]:
In [11]:
Out[11]:
In [12]:
Out[12]:
コンテナタイプ
別のコードを見てみましょう.
Pythonは3つのPyIntにメモリを割り当てる
新しいオブジェクトは作成されておらず、
元
さらに
まずこのリストを作成し、変数
このプロセスを検証します.
In [13]:
付与値、
In [14]:
In [15]:
Out[15]:
修正
In [16]:
In [17]:
変更
In [18]:
In [1]:
x = [1, 2, 3]
y = x
x[1] = 100
print y
[1, 100, 3]
変数
x
の値を変更し、変数y
の値も変更します.これはPython内部の付与メカニズムと関係があります.単純なタイプ.
まず、このコードのPythonでの実行手順を見てみましょう.
x = 500
y = x
y = 'foo'
x = 500
Pythonには
PyInt
大きさのメモリが割り当てられているpos1
オブジェクトを格納するために使用されている500
そして、Pythonはネーミングスペースで変数x
このメモリを指しています.整数は可変タイプなので、このメモリの内容は可変ではありません.メモリネーミングスペースpos1 : PyInt(500)
(可変)x : pos1
y = x
Pythonは、変数
y
の値を新しいメモリで格納するのではなく、ネーミングスペースで変数y
変数x
と同じメモリスペースを指す.メモリネーミングスペースpos1 : PyInt(500)
(可変)x : pos1
y : pos1
y = 'foo'
Pythonはこのとき
PyStr
大きさのメモリpos2
オブジェクトを格納するfoo
変数y
対象を変更する.メモリネーミングスペースpos1 : PyInt(500)
(可変)pos2 : PyStr('foo')
(可変)x : pos1
y : pos2
この手順を検証するには、
id
関数を使用します.id(x)
変数
x
のメモリアドレスを返します.In [2]:
x = 500
id(x)
Out[2]:
48220272L
In [3]:
y = x
id(y)
Out[3]:
48220272L
is
を使って、同じものを指しているかどうかを判断することもできます.In [4]:
x is y
Out[4]:
True
現在
y
別のメモリへ:In [5]:
y = 'foo'
id(y)
Out[5]:
39148320L
In [6]:
x is y
Out[6]:
False
Pythonは、表示される各オブジェクトに値が同じであっても値を割り当てます.たとえば、次のようにします.
In [7]:
x = 500
id(x)
Out[7]:
48220296L
In [8]:
y = 500
id(y)
Out[8]:
48220224L
In [9]:
x is y
Out[9]:
False
ただし、メモリの使用効率を向上させるために、数値の小さいintオブジェクトなどの簡単なオブジェクトに対して、Pythonはオブジェクトメモリを再利用する方法を採用しています.
In [10]:
x = 2
id(x)
Out[10]:
6579504L
In [11]:
y = 2
id(y)
Out[11]:
6579504L
In [12]:
x is y
Out[12]:
True
コンテナタイプ
別のコードを見てみましょう.
x = [500, 501, 502]
y = x
y[1] = 600
y = [700, 800]
x = [500, 501, 502]
Pythonは3つのPyIntにメモリを割り当てる
pos1
・pos2
pos3
(可変)を割り当て、リストにメモリを割り当てるpos4
3つの場所を含み、それぞれ3つのメモリを指し、最後に変数x
をこのリストに指し示す.メモリネーミングスペースpos1 : PyInt(500)
(可変)pos2 : PyInt(501)
(可変)pos3 : PyInt(502)
(可変)pos4 : PyList(pos1, pos2, pos3)
(可変)x : pos4
y = x
新しいオブジェクトは作成されておらず、
y
を指すpos4
でよい.メモリネーミングスペースpos1 : PyInt(500)
(可変)pos2 : PyInt(501)
(可変)pos3 : PyInt(502)
(可変)pos4 : PyList(pos1, pos2, pos3)
(可変)x : pos4
y : pos4
y[1] = 600
元
y[1]
この位置はpos2
、修正できないpos2
の値なので、まずは600
新メモリの割り当てpos5
.さらに
y[1]
指す位置をpos5
に変更します.このとき、pos2
位置のオブジェクトが使用されなくなったため、Pythonは自動的にゴミ処理メカニズムを呼び出して回収します.メモリネーミングスペースpos1 : PyInt(500)
(可変)pos2 :
ゴミ回収pos3 : PyInt(502)
(可変)pos4 : PyList(pos1, pos5, pos3)
(可変)pos5 : PyInt(600)
(可変)x : pos4
y : pos4
y = [700, 800]
まずこのリストを作成し、変数
y
を指します.メモリネーミングスペースpos1 : PyInt(500)
(可変)pos3 : PyInt(502)
(可変)pos4 : PyList(pos1, pos5, pos3)
(可変)pos5 : PyInt(600)
(可変)pos6 : PyInt(700)
(可変)pos7 : PyInt(800)
(可変)pos8 : PyList(pos6, pos7)
(可変)x : pos4
y : pos8
このプロセスを検証します.
In [13]:
x = [500, 501, 502]
print id(x[0])
print id(x[1])
print id(x[2])
print id(x)
48220224
48220248
48220200
54993032
付与値、
id(y)
id(x)
と同じ.In [14]:
y = x
print id(y)
54993032
In [15]:
x is y
Out[15]:
True
修正
y[1]
、id(y)
変わりません.In [16]:
y[1] = 600
print id(y)
54993032
id(x[1])
とid(y[1])
の値が変わりました.In [17]:
print id(x[1])
print id(y[1])
48220272
48220272
変更
y
の値、id(y)
の値変更In [18]:
y = [700, 800]
print id(y)
print id(x)
54995272
54993032