Mutability
Announcements
Objects
(Demo)
Objects
•Objects represent information
•They consist of data and behavior, bundled together to create abstractions •Objects can represent things, but also properties, interactions, & processes •A type of object is called a class; classes are first-class values in Python •Object-oriented programming:
•A metaphor for organizing large programs
•Special syntax that can improve the composition of programs •In Python, every value is an object
• All objects have attributes
• A lot of data manipulation happens through object methods • Functions do one thing; objects do many related things
4
Example: Strings
(Demo)
Representing Strings: the ASCII Standard
000 001 010 011 100 101 110 111
American Standard Code for Information Interchange
“Bell” (\a)
“Line feed” (\n)
16 columns: 4 bits
•Layout was chosen to support sorting by character code •Rows indexed 2-5 are a useful 6-bit (64 element) subset •Control characters were designed for transmission
(Demo)
6
8 rows: 3 bits
Representing Strings: the Unicode Standard
•137,994 characters in Unicode 12.1
•150 scripts (organized)
•Enumeration of character properties, such as case
•Supports bidirectional display order •A canonical name for every character
LATIN CAPITAL LETTER A
DIE FACE-6
EIGHTH NOTE
http://ian-albert.com/unicode_chart/unichart-chinese.jpg
‘⚅’ ‘♪’ (Demo)
7
Mutation Operations
Some Objects Can Change
jessica
same_person
👧
OLDER WBGOAIMBRAYLN
Only objects of mutable types can change: lists & dictionaries {Demo}
WOMAN
All names that refer to the same object are affected by a mutation
[Demo]
First example in the course of an object changing state
The same object can change in value throughout the course of computation
👵
👩
👶
Unicode
character
name
9
Mutation Can Happen Within a Function Call
A function can change the value of any object in its scope
>>>four=[1,2,3,4] >>> len(four)
4
>>> mystery(four)
>>> len(four)
2
>>> four = [1, 2, 3, 4]
>>> len(four)
4
>>> another_mystery() # No arguments!
>>> len(four)
2
defmystery(s): or defmystery(s): s.pop() s[2:] = [] s.pop()
def another_mystery():
four.pop()
four.pop()
10
pythontutor.com/composingprograms.html#code=def%20mystery%28s%29%3A%0A%20%20%20%20s.pop%28%29%0A%20%20%20%20s.pop%28%29%0A%0Afour%20%3D%20[1,%202,%203,%204]%0Amystery%28four%29&mode=display&origin=composingprograms.js&cumulative=true&py=3&rawInputLstJSON=[]&curInstr=0
Tuples
(Demo)
Tuples are Immutable Sequences
Immutable values are protected from mutation
>>> turtle = (1, 2, 3)
>>> turtle = [1, 2, 3]
>>> ooze()
>>> turtle
[‘Anything could be inside!’]
>>> ooze()
>>> turtle
(1, 2, 3)
Next lecture: ooze can
change turtle’s binding
The value of an expression can change because of changes in names or objects
Name change:
>>> x = 2
>>> x + x
4
>>> x = 3
>>> x + x
6
Object mutation:
>>> x = [1, 2]
>>> x + x
[1, 2, 1, 2]
>>> x.append(3)
>>> x + x
[1, 2, 3, 1, 2, 3]
An immutable sequence may still change if it contains a mutable value as an element
>>> s = ([1, 2], 3)
>>> s[0] = 4
ERROR
>>> s = ([1, 2], 3)
>>> s[0][0] = 4
>>> s
([4, 2], 3)
12
Mutation
Sameness and Change
• As long as we never modify objects, a compound object is just the totality of its pieces
• A rational number is just its numerator and denominator
• This view is no longer valid in the presence of change
• A compound data object has an “identity” in addition to the pieces of which it is composed • A list is still “the same” list even if we change its contents
• Conversely, we could have two lists that happen to have the same contents, but are different
>>> a = [10]
>>> b = a
>>> a == b
True
>>> a.append(20)
>>> a
[10, 20]
>>> b
[10, 20]
>>> a == b True
>>> a = [10]
>>> b = [10]
>>> a == b
True
>>> b.append(20)
>>> a
[10]
>>> b
[10, 20]
>>> a == b
False
14
Identity Operators
Identity
evaluates to True if both
Equality
evaluates to True if both
Identical objects are always equal values
(Demo)
15
Mutable Default Arguments are Dangerous
A default argument value is part of a function value, not generated by a call
>>> def f(s=[]):
… s.append(3)
…
…
>>> f()
1
>>> f()
2
>>> f()
3
return len(s)
Each time the function
is called, s is bound
to the same value!
16
pythontutor.com/composingprograms.html#code=def%20f%28s%3D[]%29%3A%0A%20%20%20%20s.append%283%29%0A%20%20%20%20return%20len%28s%29%0A%20%20%20%20%0Af%28%29%0Af%28%29%0Af%28%29&mode=display&origin=composingprograms.js&cumulative=true&py=3&rawInputLstJSON=[]&curInstr=0
Mutable Functions
A Function with Behavior That Varies Over Time
Let’s model a bank account that has a balance of $100
>>> withdraw = make_withdraw_list(100)
In a (mutable) list
referenced in the parent
frame of the function
Return value:
remaining balance
Different
return value!
>>> withdraw(25)
75
>>> withdraw(25)
50
Argument:
amount to withdraw
Second withdrawal of
the same amount
>>> withdraw(60)
‘Insufficient funds’
>>> withdraw(15) Where’s this balance 35 stored?
18
Mutable Values & Persistent Local State
withdraw doesn’t
reassign any name
within the parent
It changes the contents
of the b list
Name bound
outside of
withdraw def
Element
assignment
changes a list
19