Python賦課メカニズム

5179 ワード

まず例を見てみましょう.
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にメモリを割り当てるpos1pos2pos3(可変)を割り当て、リストにメモリを割り当てるpos43つの場所を含み、それぞれ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