1 of 36

Class Attributes

Jake Shoudy

Nov 2, 2022

CSCI 110 - Lecture 29

2 of 36

Announcements

3 of 36

HW9

Advanced dictionaries practice

Due Sunday November 6th at 11:59pm

4 of 36

Project 2: Part 3

Last part of project 2!

Convert the 2D list to dictionaries and make some more search functions!

Due Sunday November 13th at 11:59pm

5 of 36

Quiz 8

“Advanced” dictionaries (dictionaries w/ lists/dictionaries as values, similar to HW9)

Meet in Lab downstairs for first 15 minutes of class

6 of 36

7 of 36

Next week: Career week!

Lecture MWF will be “guest lectures” by Googlers (virtually) about miscellaneous computer science topics. You should still come in person!

3 PD hours available for attending lecture

Tuesday (lab) will be an optional interview prep workshop hosted by me!

8 of 36

Final Exam Date!

Tuesday 11/29 during normal lab hours

  • 8-10am
  • 12:30-2:20pm
  • 3-4:50pm

9 of 36

Practice Version of Exams

Updated Exam 1, Exam 2, Practice Exam 1, Practice Exam 2 to have two versions:

  • (Answer Key) - this is the actual test you took where you can see your answers as well as the solutions
  • (Practice Version) - this is a clone of the tests that you can take again in order to simulate the timing of an exam.

10 of 36

Recap

11 of 36

Classes

A class lets you define your own type.

Think of a class to be a bundle of

  • class attributes (which hold data)
  • class methods (which are functions tied to the class)

The class definition serves as a template for its instances. Then an object is an instance of a particular class.

class <Name>:

<suite>

12 of 36

Classes

The class definition almost always has a special class method called `__init__`

__init__ is a special class method that is called when you create an instance of the class. It is called the constructor of the class, and always has `self` as the first parameter (for which you don’t pass anything in), followed by any parameters you need to use to construct an instance of the class.

class <Name>:

def __init__(self, param1, ...):

self.attribute = param1

...

13 of 36

Defining a Class

For our character example…

class Character:

def __init__(self, char_name, str_score, def_score):

self.health = 100

self.name = char_name

self.strength = str_score

self.defense = def_score

def introduce(self):

print("Hi, my name is " + self.name)

14 of 36

Creating a Class Instance

We create an instance of our class by calling the name of the class like a function call, and passing in any arguments that the `__init__` method needs.

woodie = Character("Woodie", 15, 7)

pickie = Character("Pickie", 12, 8)

15 of 36

Class attributes

16 of 36

Attributes

Attributes don’t get stored in any frame. Rather, they are stored as part of the object (similar to a list or dictionary)

woodie = Character("Woodie", 15, 7)

attributes

Two main ways to set attributes:

  1. instance attributes via instance object
  2. “default” class attributes in class definition

17 of 36

Instance Attributes

These are attributes set by assigning to the instance of a class. They can be set via:

  • `self.attribute_name = value` inside of a class
  • `variable_name.attribute_name = value` outside of the class

They can be accessed via:

  • `self.attribute_name` inside of a class
  • `variable_name.attribute_name` outside of a class

Instance attributes are unique to that instance of a class

18 of 36

Instance Attributes

class Character:

birthplace = "Kingdom of Asgardia"

def __init__(self, char_name, str_score, def_score):

self.health = 100

self.name = char_name

self.strength = str_score

self.defense = def_score

woodie = Character("Woodie", 15, 7)

woodie.favorite_color = "Blue"

print(woodie.favorite_color) # prints “Blue”

print(woodie.health) # prints 100

woodie.health = 90

print(woodie.health) # prints 90

19 of 36

Class Attributes

These are the kind of attributes set directly in the class definition (not in the constructor and not on the self parameter). Thes can be set via:

  • `attribute_name = value` inside of the class
  • `ClassName.attribute_name = new_value` either inside or outside the class

The can be accessed via:

  • `ClassName.attribute_name` wherever
  • `variable_name.attribute_name` if there is no instance variable already using that attribute name

Is shared among all instances of the class

20 of 36

Class Attributes

class Character:

birthplace = "Kingdom of Asgardia"

def __init__(self, char_name, str_score, def_score):

self.health = 100

self.name = char_name

self.strength = str_score

self.defense = def_score

woodie = Character("Woodie", 15, 7)

pickie = Character("Pickie", 23, 4)

print(woodie.birthplace) # prints “Kingdom of Asgardia”

print(Character.birthplace) # prints “Kingdom of Asgardia”

pickie.birthplace = "Helm’s deep"

Character.birthplace = "Narnia"

print(pickie.birthplace) # prints “Helm’s deep”

print(Character.birthplace) # prints “Narnia”

print(woodie.birthplace) # prints “Narnia”

21 of 36

Referencing Attributes

Careful to only reference attributes that you know to exist. If you try to reference an attribute that doesn’t exist, Python will throw an AttributeError:

woodie = Character("Woodie", 15, 7)

print(woodie.age)

22 of 36

Referencing Attributes

This also happens when we try to access an instance attribute via the class.

woodie = Character("Woodie", 15, 7)

print(Character.name)

23 of 36

Printing a class

Printing an instance of a class just tells us the location in memory where the object is stored. Not very useful…

woodie = Character("Woodie", 15, 7)

print(woodie)

24 of 36

__str__ method

Tells python how to represent our class as a string

  • Always named “__str__”
  • Always takes in “self” as the only parameter to represent the current instance
  • Must return a string which will be used to represent the instance of a class

25 of 36

__str__ method

We have to tell python how to print out an instance of a Character class

class Character:

def __init__(self, char_name, str_score, def_score):

self.health = 100

self.name = char_name

self.strength = str_score

self.defense = def_score

def __str__(self):

status = “Name: {}\nStrength: {}\nDefense: {}”

return status.format(self.name, self.strength, self.defense)

26 of 36

Printing a class

Now that we have the __str__ method…

woodie = Character("Woodie", 15, 7)

print(woodie)

27 of 36

Equality

28 of 36

is operator

Objects that are instances of classes that you define are mutable.

  • Therefore they are also passed-by-reference in a function call.

We can use the `is` operator to check if two variables refer to the same instance.

woodie = Character("Woodie", 15, 7)

pickie = Character("Pickie", 12, 8)

print(woodie is pickie) # Prints False

print(woodie is woodie) # Prints True

29 of 36

Object Identity

Even though these have the same attributes, they are different instances! `is` operator doesn’t compare attributes, it checks if they are the same instance.

player_1 = Character("Woodie", 15, 7)

player_2 = Character("Woodie", 15, 7)

print(player_1 is player_2)

False

What does this print?

30 of 36

is vs ==

`is` operator checks if two variables are the exact same instance (i.e. if the data is actually in the same memory location)

`==` operator checks if two variables have the same values

a = [1, 2, 3]

b = [1, 2, 3]

c = a

print(a is b) # Prints False

print(a == b) # Prints True

print(a is c) # Prints True

31 of 36

== operator

So if we want to check if two classes have the same values we should use the `==` operator!

player_1 = Character("Woodie", 15, 7)

player_2 = Character("Woodie", 15, 7)

print(player_1 == player_2)

False

32 of 36

__eq__ method

Tells python what it means for two instances of the same object to be equal

  • Always named “__eq__”
  • Always takes in “self” as the first parameter to represent the current instance
  • Always takes a second parameter to represent the other instance it is being compared to
  • Must return True or False with the result of the equality check

33 of 36

__eq__ method

We have to tell python what it means for two Characters to be equal

class Character:

def __init__(self, char_name, str_score, def_score):

self.health = 100

self.name = char_name

self.strength = str_score

self.defense = def_score

def __eq__(self, other):

return self.name == other.name

34 of 36

== operator

Now we can use the `==` operator!

player_1 = Character("Woodie", 15, 7)

player_2 = Character("Woodie", 15, 7)

print(player_1 == player_2)

True

35 of 36

== operator

Now we can use the `==` operator!

player_1 = Character("Woodie", 21, 8)

player_2 = Character("Woodie", 15, 2)

print(player_1 == player_2)

True

36 of 36

Let’s Code!