Classes

Calvin (Deutschbein)

W10Wed: 30 Oct

Announcements

  • Project 3 next Monday.
    • Milestone 3 tonight
    • Milestone 4a by Thursday
    • Milestone 4b by Friday
    • Milestone 4c by Saturday
  • Midterm looming. Stay tuned.

Today

  • Classes
    • Editorializing
    • Classes and Objects
    • Definitions and Applications
    • Attributes
    • Initialization

Editorializing

  • My minority take: Classes are bad
    • Classes bundle data and computing non-obviously. "".join("hi","world") # this works join("hi","world") # this doesn't "".len("hi") # this doesn't len("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. >>> def do_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
    class Box: 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. class Box: 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.
    class Box: pass def boxify(): return

Attributes

  • Imagine we have an 'x' inside a box... an 'x' 'box' if you will.
    class XBox: # turn 360 walk away x = 360 def xboxify(): # 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.
    >>> class XBox: ... x = 360 ... return x ... File "<stdin>", line 3 SyntaxError: 'return' outside function >>> def xboxify(): ... x = 360 ... return x ... >>> xboxify() 360

Attributes

  • Imagine we have an 'x' inside a box... an 'x' 'box' if you will.
    class XBox: x = 360 def xboxify(): x = 360 return 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.
    class XBox: # loneliest # x = 1 def xboxify(): # 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
    class XBox: def __init__(self, val): x = val def xboxify(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.
  • class XBox: def __init__(self, val): x = val

Initialization

  • Let's examine this.
  • class XBox: def __init__(self, val): x = val
  • 'def' we already know

Initialization

  • Let's examine this.
  • class XBox: 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.
  • class XBox: 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__' is not defined

Initialization

  • We can print inside an init to see what's happening...
  • class XBox: def __init__(self, val): x = 1 print(x) x = val print(x)
  • It prints just fine, but...
  • >>> b = XBox(360) 1 360
  • 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.
  • class XBox: def __init__(self, val): self.x = 1 print(self.x) self.x = val print(self.x)
  • It prints just fine, but...
  • >>> b = XBox(9) 1 360 >>> b.x 360

Initialization

  • Another way.
  • class XBox: x = 360 def __init__(self, val): print(self.x) self.x = val print(self.x)
  • It prints just fine, but...
  • >>> b = XBox(1) 360 1 >>> b.x 1
  • Always remember the difference between an XBox 360 and XBox 1.

Today

  • Classes
    • ✓ Editorializing
    • ✓ Classes and Objects
    • ✓ Definitions and ApplicationInstantiation
    • ✓ Attributes
    • ✓ Initialization

Announcements

  • Project 3 next Monday.
    • Milestone 3 by tonight
    • Milestone 4a by Thursday
    • Milestone 4b by Friday
    • Milestone 4c by Saturday
  • Looming midterm.