Classes bundle data and computing non-obviously.
"".join("hi","world") # this works
join("hi","world") # this doesn't"".len("hi") # this doesn'tlen("hi") # this does
Classes make tracking data confusing
a, b = [1], [1]
c = b
c is b, c == b # True, True
c is a, c == a # False, True
I refer to this as "the Java problem" but it impacts all modern languages.
Editorializing
Editorializing
Editorializing
Takeaways
Finding classes confusing is valid.
Finding classes tedious is valid.
Think critically about what you learn / are taught!
Future trends are ambigious
I expect: more types, fewer classes.
For DATA 151 students: R is the other kind of language - functional.
Today
Classes
✓ Editorializing
Classes and Objects
Definitions and Applications
Attributes
Initialization
Classes and Objects
A class is a kind of thing.
Like an int or a list.
Or like CS 152
An object is "instance" of a class
Like '7' or '123'
Or like Sping 2025 Section 1
>>> list, type(list)
(<class 'list'>, <class 'type'>) # a class>>> list(), type(list()) # an object
([], <class 'list'>)
Objects
In Python, everything is an object or some class.
An integer is an object of the int class
A string is an object of the str class
'print' is an object of the function class
Yes - functions are a class too.
>>> defdo_thing():... 1 == 1
...
>>> type(do_thing)
<class 'function'>>>> do_thing
<function do_thing at 0x00000298D0845120>
Today
Classes
✓ Editorializing
✓ Classes and Objects
Definitions and Application
Attributes
Initialization
Define
Like functions, classes are defined.
They use "class" instead of "def"
My first class was something called "Box" because I thought of it as a box within which I could store some data, like the number 7.
In this way, they are another way to do records, like we did with tuples on Monday
classBox:pass
Like functions, they need something inside for indentation - I place the term "pass".
By convention, class names are Capitalized.
Apply
Like functions, classes are defined.
classBox:pass
Like functions, we use classes by taking their name and appending parens to the end.
>>> b = Box()
With functions, we termed this "application".
We "applied" a function, like "add these together", to some values
With classes, this is called "instantiation".
Rather than return a value from a function, class instantion "creates" (not returns really) an instance of the class.
How do these differ?
Today
Classes
✓ Editorializing
✓ Classes and Objects
✓ Definitions and ApplicationInstantiation
Attributes
Initialization
Attributes
Classes can hold data inside of them.
These are basically variables inside another variable.
They are officially called "attributes" and sometimes called "fields" or "properties" (if you go on Google etc).
Let's compare 'Box' to 'boxify' to see what an attribute does.
classBox:pass
defboxify():return
Attributes
Imagine we have an 'x' inside a box... an 'x' 'box' if you will.
classXBox:# turn 360 walk away
x = 360
defxboxify():# I'm so Julia
x = 360
We can interface with attributes, but cannot do the same for function variables!
b = XBox()
print(b.x) # prints 7
b = xboxify()
print(b.x) # error
Attributes
Functions can return values of any types, but class instantions do not.
>>> classXBox:... x = 360... return x
...
File "<stdin>", line 3
SyntaxError: 'return' outside function
>>> defxboxify():... x = 360... return x
...
>>> xboxify()
360
Attributes
Imagine we have an 'x' inside a box... an 'x' 'box' if you will.
classXBox:
x = 360
defxboxify():
x = 360return x
We can change attributes after instantiating the object!
b = XBox()
b.x = 1
print(b.x) # prints 1
x = 1
b = xboxify()
print(b) # prints 360
We can't add 1 to the 'x' inside of xboxify because... there isn't really an 'x' there?
Today
Classes
✓ Editorializing
✓ Classes and Objects
✓ Definitions and ApplicationInstantiation
✓ Attributes
Initialization
Initialization
Imagine we have an 'x' inside a box... an 'x' 'box' if you will.
classXBox:# loneliest #
x = 1
defxboxify():# we are # 1
x = 1
We probably don't want the same 'x' every time.
We want to be able to do this:
b = XBox(1)
b = xboxify(1)
Initialization
In classes, this is resolved via initialization, which is implemented with "double underscores" like so:
Note the indentation level
classXBox:def__init__(self, val):
x = val
defxboxify(val):
x = val
return x
We probably don't want the same 'x' every time.
We want to be able to do this:
b = XBox(1)
b.x # is 1
b = xboxify(1)
b # is 1
Initialization
Let's examine this.
classXBox:def__init__(self, val):
x = val
Initialization
Let's examine this.
classXBox:def__init__(self, val):
x = val
'def' we already know
Initialization
Let's examine this.
classXBox:def__init__(self, val):
x = val
'def' we already know
'__init__' is a special built-in name
'init' is called when the object is instanted
It may accept arguments!
Initialization
Let's examine this.
classXBox:def__init__(self, val):
x = val
'def' we already know
'__init__' is a special built-in name
'init' is called when the object is instanted
It may accept arguments!
'self' refers to the object being instantiated!
If we just say "__init__" in Python, it won't work...
>>> __init__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name '__init__'isnot defined
Initialization
We can print inside an init to see what's happening...
classXBox:def__init__(self, val):
x = 1
print(x)
x = val
print(x)
It prints just fine, but...
>>> b = XBox(360)
1360
We can no longer see 'x' from outside.
>>> b.x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'XBox'object has no attribute 'x'
Initialization
We use "self.x" to refer the 'x' of the object.
Otherwise, that is just the x of the __init__ function.
classXBox:def__init__(self, val):
self.x = 1
print(self.x)
self.x = val
print(self.x)
It prints just fine, but...
>>> b = XBox(9)
1360>>> b.x
360
Initialization
Another way.
classXBox:
x = 360def__init__(self, val):
print(self.x)
self.x = val
print(self.x)
It prints just fine, but...
>>> b = XBox(1)
3601>>> b.x
1
Always remember the difference between an XBox 360 and XBox 1.