Classes: make your own types
So far your data and your functions have lived apart. A player might be a dictionary, and a separate function changes its health. That works until you have ten functions and five kinds of thing, and nobody remembers which function goes with which dictionary.
A class bundles the two together. It is a blueprint for making objects that carry their own data and their own functions:
class Player:
def __init__(self, name, health):
self.name = name
self.health = health
def take_hit(self, damage):
self.health = self.health - damage
Reading it line by line:
class Player:starts the blueprint. Class names use CapitalWords.__init__(two underscores each side) runs automatically when you make a new object. Its job is to set up the starting data.selfis the object being worked on.self.name = namestores the name on that object, as an attribute.take_hitis a method: a function that belongs to the class. Every method getsselffirst, so it can read and change that object's attributes.
Making objects and using them:
zoe = Player("Zoe", 100)
sam = Player("Sam", 80)
zoe.take_hit(30)
print(zoe.health) # 70
print(sam.health) # 80, Sam was not touched
Player("Zoe", 100) calls __init__ for you, with self filled in. You never pass self yourself; Python does it. Each object has its own copy of the attributes, which is the whole point.
The most common beginner bug here is forgetting self. inside a method. Writing health = health - damage makes a brand new local variable that vanishes when the method ends, and the object's real health never changes.
You have been using objects since lesson 1, by the way. A string is an object, and .upper() is one of its methods.
Try it yourself
Edit it. Break it. Run it again.class Player:
def __init__(self, name, health):
self.name = name
self.health = health
def take_hit(self, damage):
self.health = self.health - damage
def is_alive(self):
return self.health > 0
def describe(self):
return f"{self.name} has {self.health} HP"
zoe = Player("Zoe", 100)
sam = Player("Sam", 40)
zoe.take_hit(30)
sam.take_hit(50)
print(zoe.describe())
print(sam.describe())
print("Sam still in the game?", sam.is_alive())
Your turn
Type it yourself. That is the whole trick.1A bank account
Finish the Account class. deposit(amount) should add to the balance and withdraw(amount) should take it away. The balance starts at whatever __init__ is given.
class Account:
def __init__(self, owner, balance):
self.owner = owner
self.balance = balance
def deposit(self, amount):
balance = self.balance + amount
def withdraw(self, amount):
pass
2A to-do list object
Write a class TodoList. __init__ takes no extra arguments and starts an empty list in self.items. add(task) appends a task. count() returns how many tasks there are.
class TodoList:
pass