Subscribed unsubscribe Subscribe Subscribe

Python で mutable と immutable の違い


f:id:domodomodomo:20161101225023p:plain

煽らないでください。

簡単に言えば...

を変更できるオブジェクトのことを mutable と呼びます。

生成後にを変更できないオブジェクトのことを immutable と呼びます。

3. Data model — Python 3.5.3 documentation

○ mutable なオブジェクトの例

例えば、list 型、 dict 型、ユーザが定義した型(クラス)は mutable です。Python において型とクラスは、同義です。

>>> class Person():
...   def __init__(self, name):
...     self.name = name
... 
>>> 
>>> person = Person('yaruo')
>>> 
>>> person.name
'yaruo'
>>> 
>>> # value 値を変更できた -> mutable
>>> person.name = 'yarumi' 
>>> person.name
'yarumi'

○ immutable なオブジェクトの例

例えば、数値型、文字列型とタプル型のインスタンスは immutable です。

>>> t = ('yaruo', 'yaranaio')
>>> 
>>> t
('yaruo', 'yaranaio')
>>>
>>> t[0]
'yaruo'
>>> 
>>> # value 値を変更できない -> immutable
>>> t[0] = 'yarumi'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

値 value とは

属性 attribute に代入されているインスタンスオブジェクトのことを指していると "思われます" 。
 

この辺りの用語的な定義やら何やらを探してますが、まだそれと思しきものを見つけられないでいます...。

ただ、色々読んでると Python で言う値 value ってのは、上記のような理解に落ち着くのかなと思っています。

でも、そう考えると、オブジェクトと値の関係も、再帰的に定義されてそうな気配がありますね。

object には複数の attribute がついていて
attribute には 1 つの value(object) が結びついてる的な...
object -*-> attribute -1-> value(object)

 

属性 attribute に代入される値 value を変更できないものを immutable って言う理解でいいのかな...?



もう少し詳しく...

さらにマニュアルの文言を見てみましょう。

従って immutable であること (immutability) は、厳密に言えば "値が変更できないこと" と同義ではなく、もう少し複雑です。

So, immutability is not strictly the same as having an unchangeable value, it is more subtle.

3. Data model — Python 3.5.3 documentation

 

え?違うの?immmutable なオブジェクトでも値を変更できるそうです。それはどのようなオブジェクトでしょうか?さらにさらにマニュアルの文言を見てみましょう。

mutable object への参照を持っている immutable container object の値は、参照している mutable object の値が変化させられた時に変化すると言えます。しかしながら container は immutable であると判断されます、

The value of an immutable container object that contains a reference to a mutable object can change when the latter’s value is changed; however the container is still considered immutable,


なぜなら container が所持しているオブジェクトの集合は変化していないからです。従って immutable であること (immutability) は、厳密に言えば "値が変更できないこと" と同義ではなく、もう少し複雑です。

because the collection of objects it contains cannot be changed. So, immutability is not strictly the same as having an unchangeable value, it is more subtle.

3. Data model — Python 3.5.3 documentation

 

immmutable なオブジェクトでも値を変更できる具体例として mutable object への参照を持っている immutable container object というのが出てきました。

これは一体何やねん。一つ一つ見ていきたいと思います。



Step1. object

「変数に格納できるもの」が、インスタンスオブジェクトだと理解しています。一応 Python は全てがオブジェクトらしいです。
Pythonのオブジェクトとクラスのビジュアルガイド – 全てがオブジェクトであるということ | プログラミング | POSTD


Step2. immutable object

numbers, strings, tuples は immutable です。

オブジェクトが mutable かどうかはその型によって決まります。例えば、数値型、文字列型とタプル型のインスタンスは immutable で、dict や list は mutable です。

An object’s mutability is determined by its type; for instance, numbers, strings and tuples are immutable, while dictionaries and lists are mutable.

3. Data model — Python 3.5.3 documentation

Step3. container object

ほぼほぼ全てのオブジェクトが複数の属性を持っているので、ほぼほぼ全てのオブジェクトがcontainer オブジェクトだって認識でいいのではないでしょうか... int も複数の値を持ってますしね。

コンテナとはオブジェクトの集まりを表現するデータ構造、抽象データ型またはクラスの総称である。

コンテナ (データ型) - Wikipedia

Step4. immutable container object

Step2, 3 を踏まえると...
numbers, strings, tuples は immutable container object と言えそうですね。

Step5. mutable object への参照を持っている immutable container object

タプル t がそれに該当します。さっそく値を変更できる immutable なオブジェクトを見てみましょう。

>>> 
>>> # mutable なオブジェクト a, b, c
>>> class A():
...   a = "nihao"
... 
>>> 
>>> class B():
...   b = "hello"
... 
>>> 
>>> class C():
...   c = "hola"
... 
>>> 
>>> a = A()
>>> b = B()
>>> c = C()
>>> 
>>>
>>> #
>>> # tuple は immutable
>>> #
>>>
>>> #
>>> # mutable なオブジェクト a, b, c への参照を持つ
>>> # immutable なオブジェクト t
>>> # 
>>>
>>> t = (a, b, c)
>>>
>>>
>>> #
>>> # t はタプル immutable なので
>>> #  オブジェクトの代入できない。
>>> #  参照しているオブジェクトを切り替えられない。
>>> # 
>>>
>>> t[2] = a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> 
>>> t[2].c
'hola'
>>> 
>>> #
>>> # でも タプル t の中の c は mutable なので
>>> # オブジェクトを変更できる。
>>> #
>>>
>>> t[2].c = "konnichiwa"
>>> 
>>> t[2].c
'konnichiwa'
>>> 

まとめ

mutable ... 値(オブジェクト)の集合を変更できる
immutable ... 値(オブジェクト)の集合を変更できない
 

しかしながら container (an immutable container object) は immutable であると判断されます、なぜなら container が所持しているオブジェクトの集合は変化していないからです。

however the container (an immutable container object) is still considered immutable, because the collection of objects it contains cannot be changed.

3. Data model — Python 3.5.3 documentation




Remove all ads