References
# ------------------------------------
# REFERENCES
# ------------------------------------
# Variables are names bound to objects.
# Assigning one variable to another
# copies the reference, not the object.
#
# In Python everything is an object.
a = [1, 2, 3] # a references the list object
b = a # b references the SAME list object
b.append(4) # modify the list through b
print(a) # [1, 2, 3, 4]
print(b) # [1, 2, 3, 4]
assert a == b # a and b point to the same list in memory
# ----------------------------------------
# HASH vs REFERENCE
# ----------------------------------------
# There are three different things people often mix up:
# 1. The variable names (a, b)
# 2. The object in memory (the list [1, 2, 3, 4])
# 3. The has of an object (used for dictionary keys)
#
# Variables don't have hashes.
# Only objects can have a hash.
#
# The list object has no hash, because lists are mutable.
# Hashes must never change.
# --------------------------
# IDENTITY
# --------------------------
# Python lets you check the identity using id().
# This proves that a and b point to the same object.
a = [1, 2, 3]
b = a
print(id(a)) # 140103271591744
print(id(b)) # 140103271591744
# -----------------------------
# IMMUTABLE OBJECTS - HASHABLE
# -----------------------------
a = (1, 2, 3)
b = a
print(id(a) == id(b)) # True
print(hash(a)) # OK
print(hash(b)) # Same hash
Mutable vs Immutable
# --------------------------------------------
# MUTABLE vs IMMUTABLE
# --------------------------------------------
# Mutable: changes affect all references
# Immutable: reasignment creates a new object
# --------------------------------------------
# MUTABLE Types
# ---------------------------------------------
# LIST
# ----------
a = [1, 2, 3]
b = a # same list reference
b.append(4) # modify list reference
print(a) # [1, 2, 3, 4]
print(b) # [1, 2, 3, 4]
# DICTIONARY
# ----------
user = {'name': 'Alice', 'age': 25}
profile = user # same dictionary reference
profile['age'] = 26
print(user) # {'name': 'Alice', 'age': 26}
# SET
# ---------
fruits = {"apple", "banana"}
basket = fruits #same set reference
basket.add("orange")
print(fruits) # {'apple', 'banana', 'orange'}
# --------------------------------------------------
# IMMUTABLE Types
# --------------------------------------------------
# INTEGER
# -------
a = 10
b = a # same integer reference
b += 5 # creates a NEW integer object
print(a) # 10 (unchanged)
print(b) # 15
# STRING
# -------
a = "hello"
b = a # same string reference
b += " world" # creates a NEW string
print(a) # hello (unchanged)
print(b) # hello world
# TUPLE
# -------
a = (1, 2, 3)
b = a # same tuple reference
b += (4,) # creates a NEW tuple
print(a) # (1, 2, 3)
print(b) # (1, 2, 3, 4)
Garbage collection
# ---------------------------------------
# GARBAGE COLLECTION
# ---------------------------------------
# Python frees objects automatically
# when no references remain.
import sys
a = [1, 2, 3]
# Number of references to the object
print(sys.getrefcount(a)) # 2 (a + argument to getrefcount())
b = a # add another reference
print(sys.getrefcount(a)) # 3
del b # remove a reference
print(sys.getrefcount(a)) # 2
del a # no reference left
# Object is garbage collected automatically
Questions and answers:
Clink on Option to Answer
1. What is a variable in Python?
- a) a container used to store data
- b) a reference to an object in memory
2. What assigning a variable to another means?
- a) we are copying the value
- b) we are just copying the reference
3. When assigning creates a new object in Python?
- a) when the object is mutable
- b) when the object is immutable
4. What objects are immutable in Python?
- a) List, Dictionary, Set
- b) Integer, String, Tupple
5. How do you manage garbage collection in Python?
- a) no need, Python frees mememory automatically
- b) manually, with free() link in C