Mutable vs. immutable objekty¶
Datové typy v Pythonu se podle svých vlastností dělí na:
- mutable (modifikovatelné) – např.
list,set,dict - immutable (nemodifikovatelné) – např.
str,tuple,frozenset, všechny číselné datové typy
Modifikovatelné typy mají metody, které umožňují modifikovat daný objekt (např. přidávat nebo odebírat prvky v kontejneru). Naopak nemodifikovatelné typy nemají žádné metody, které by modifikovaly daný objekt – jediný způsob, jak dosáhnout modifikace, je tedy vytvoření nového objektu.
Přiřazení mutable objektů¶
In [14]:
# přiřazení immutable objektů ... číslo
a = 10
b = a
print(a is b) # `a` a `b` jsou identické
# změna immutable objektu
b += 2
print("a =", a) # vypíše 10
print("b =", b) # vypíše 12
print(a is b) # False
print(a == b) # False
True a = 10 b = 12 False False
In [2]:
# přiřazení immutable objektů ... tuple
a = (10, 5)
b = a
print(a is b) # `a` a `b` jsou identické
# změna immutable objektu
b += (1, 2)
print("a =", a) # vypíše (10, 5)
print("b =", b) # vypíše (10, 5, 1, 2)
print(a is b) # False
print(a == b) # False
True a = (10, 5) b = (10, 5, 1, 2) False False
In [15]:
# přiřazení mutable objektů ... list
a = [10, 5]
b = a
print(a is b) # `a` a `b` jsou identické
# změna mutable objektu
b.extend([1, 2])
print("a =", a) # vypíše [10, 5, 1, 2]
print("b =", b) # vypíše [10, 5, 1, 2]
print(a is b) # True
print(a == b) # False
True a = [10, 5, 1, 2] b = [10, 5, 1, 2] True True
In [5]:
# přiřazení mutable objektů ... set
a = {10, 5}
b = a
print(a is b) # `a` a `b` jsou identické
# změna mutable objektu
b.add(1)
print("a =", a) # vypíše {1, 10, 5}
print("b =", b) # vypíše {1, 10, 5}
print(a is b) # True
print(a == b) # False
True
a = {1, 10, 5}
b = {1, 10, 5}
True
True
Volání funkcí¶
In [18]:
# podobně pro volání funkce, kde je mutable objekt argumentem
def f(t):
t.append(1)
t.sort()
print("lokální:", t)
s = [1, 7, 2, 4]
f(s)
print("globální:", s)
lokální: [1, 1, 2, 4, 7] globální: [1, 1, 2, 4, 7]
In [19]:
# globální immutable objekt se uvnitř funkce nezmění
def f(t):
t += (1, 2)
print("lokální:", t)
s = (1, 7, 2, 4)
f(s)
print("globální:", s)
lokální: (1, 7, 2, 4, 1, 2) globální: (1, 7, 2, 4)
In [12]:
# globální immutable objekt se uvnitř funkce nezmění
def f(x):
x += 3
print("lokální:", x)
x = 4
f(x)
print("globální:",x)
lokální: 7 globální: 4
Kopírování mutable objektů¶
In [1]:
def copy_list(source):
""" Creates a new list containing all elements of the source.
Does **not** modify the parameter.
"""
copy = []
for element in source:
copy.append(element)
return copy
In [16]:
a = [1, 3]
b1 = copy_list(a)
b2 = list(a)
b3 = a.copy()
b4 = a[ : ]
print(a is b1, a is b2, a is b3, a is b4)
a.append(2)
print(a)
print(b1, b2, b3, b4)
False False False False [1, 3, 2] [1, 3] [1, 3] [1, 3] [1, 3]
In [12]:
a = {1, 3}
b1 = set(a)
b2 = a.copy()
print(a is b1, a is b2)
a.add(2)
print(a)
print(b1, b2)
False False
{1, 2, 3}
{1, 3} {1, 3}
In [13]:
a = {1: "a", 3: "b"}
b1 = dict(a)
b2 = a.copy()
print(a is b1, a is b2)
a[5] = "c"
print(a)
print(b1, b2)
False False
{1: 'a', 3: 'b', 5: 'c'}
{1: 'a', 3: 'b'} {1: 'a', 3: 'b'}