すべてのエンティティがオブジェクトであるPythonにおいて、immutableとはどのような意味ですか?変数に代入するデータの型を明示的に指定する必要がある他のプログラミング言語とは異なり、Pythonではその必要がありません。
その代わり、与えられた値に応じて自動的にデータ型が割り当てられます。
つまり、各変数はオブジェクトのインスタンスを保持し、プログラムの実行時に作成される一意のオブジェクトIDが与えられます。
オブジェクトIDは、その変数の値が格納されているメモリ上の位置を表す整数です。
各オブジェクトのIDを取得するには、Python Shellを開き、デフォルトのid()関数を呼び出して変数名を渡す必要があります。
以下はその例です。
#Initializing the variable a = "this is not a random string"
#We call the id() function with the variable name as argument print ( "The Object id of 'a' is: " + str ( id (a)))
|
結果は、以下の通りです。
次の出力は
The Object id of 'a' is: 1695893310240 |
不変性とは何か?
Immutabilityの概念を正しく理解するためには、MutableなオブジェクトとImmutableなオブジェクトの違いを知る必要があります。
ミュータブルオブジェクトとは何ですか?
オブジェクトを作成した後に、そのオブジェクトの状態を変更できる場合、そのオブジェクトはmutableオブジェクトと呼ばれます。
例を挙げます。
以下では、以下のランダムな値のリストを変数「randomValues」に代入しています。
作成されたら、そのオブジェクトIDをチェックしてメモしておきます。
次に、リストを変更する必要があります(値を追加したり、削除したり、単純に1つを他のものに置き換えたりすることで実現可能です)。
そして、再びObject IDを記録します。
もしObject IDとリストのメモリ上の位置が同じであれば、Pythonのリストの状態が変更されたと言えます。
# Our list of random values randomValues = [ "Bojack Horseman" , 42 , "Robert Langdon" , 1.61803 ]
id1 = id (randomValues)
# Modifying/Changing the state of our list randomValues[ 1 ] = "The answer to everything"
randomValues.append( "I love Python" )
id2 = id (randomValues)
# Compare the object id before and after modifying if id1 = = id2:
print ( "The Object ID Remains the same." )
else :
print ( "The Object ID changes." )
|
結果は以下の通りです。
The Object ID Remains the same. |
このように、値が変化しても、リストのメモリ位置やIDは変わらないことがわかります。
これは、Pythonが追加された値を考慮し、より多くのメモリ空間をその場所に割り当てたことを意味します。
このことから、リストは “mutable “オブジェクト、つまり変更可能なオブジェクトであると言えます。
イミュータブルオブジェクトとは何ですか?
オブジェクトを作成した後、その状態を変更できないものをイミュータブルオブジェクトと呼びます。
例として以下の様になります。
前の例ではリストを使って操作しましたが、以下ではランダムな値を含むタプルを初期化します。
そして、そのオブジェクトIDを記録します。
次に、このタプルを変更し、変更前と変更後のオブジェクトIDを比較します。
# Our tuple of random values randomValues = ( "Bojack Horseman" , 42 , "Robert Langdon" , 1.61803 )
id1 = id (randomValues)
# Modifying/Changing the state of our tuple randomValues[ 1 ] = "The answer to everything"
# Compare the object id before and after modifying if id1 = = id2:
print ( "The Object ID Remains the same." )
else :
print ( "The Object ID changes." )
|
出力。
TypeError: 'tuple' object does not support item assignment |
ここで、タプル(本質的に不変の型)は、その値の変更や項目の追加をサポートしていないことがわかります。
そこで、同じ操作を整数で続けてみましょう。
例2.
今度は、単純な整数値を任意の変数に代入して、そのオブジェクトIDを記録する必要があります。
前の例と同様に、整数型変数に新しい値を代入して、オブジェクト ID を比較します。
# first we assign an integer value to the variable randomNumber = 42
id1 = id (randomNumber)
# Change the value of our integer variable randomNumber = 134
id2 = id (randomNumber)
if id1 = = id2:
print ( "The Object ID remains the same." )
else :
print ( "The Object ID changed." )
|
結果は以下の通りです。
The Object ID changed. |
ここで、新しい値を代入した後、変数 “randomNumber” のオブジェクト ID も変化したことがはっきりとわかります。
つまり、以前とは別のオブジェクトになったということです。
これは、元のオブジェクトの状態が変化したのではありません。
注:不変オブジェクトを持つ変数に新しい値を代入すると、新しいオブジェクトが作成され、現在のオブジェクトは上書きされません。
PythonでImmutableなオブジェクトは?
Pythonのimmutableという言葉の意味を理解したところで、Pythonのどのタイプのオブジェクトがimmutableなのかを見てみましょう。
- 文字列
文字列 * 整数 - 浮動小数点数
- タプル
- レンジはタプル
まとめ
Immutable Objectsの大きな利点の1つは、Mutable Objectsと比較してアクセスが非常に高速であることです。
この記事がPythonのImmutable Objectsの概念を理解する助けになることを願っています。