36 Character Classes: Creating Your Own Types
Welcome, brave Python adventurers! Today we begin an exciting new chapter in our coding journey: creating our own types using classes. Just as the world of role-playing games has different character classes (like warriors, mages, and rogues), Python allows us to create our own custom types of objects with classes. Let’s learn how to forge these powerful templates!
36.1 What is a Class?
Think of a class as a blueprint or template for creating objects. Just as all warriors in a game share certain characteristics (like strength and weapon skills), objects created from the same class share the same structure and behaviors.
Let’s create our first class - a simple template for warriors:
class Warrior:
def __init__(self, name, health):
self.name = name
self.health = health
This code creates a new type called Warrior
. The special __init__
method (called the constructor) sets up the initial attributes of each warrior we create.
36.2 Creating Objects from Classes
Once we have a class definition, we can create (or “instantiate”) objects from it:
# Create two warrior objects
= Warrior("Parzival", 100)
hero = Warrior("Galahad", 95)
companion
# Access their attributes
print(f"{hero.name} has {hero.health} health")
print(f"{companion.name} has {companion.health} health")
This will output:
Parzival has 100 health
Galahad has 95 health
Each object we create from the Warrior
class is called an instance, and each has its own set of attributes (name
and health
in this case).
36.3 Adding More Attributes
We can make our warriors more interesting by giving them more attributes:
class Warrior:
def __init__(self, name, health, strength, weapon):
self.name = name
self.health = health
self.strength = strength
self.weapon = weapon
# Create a more detailed warrior
= Warrior("Parzival", 100, 15, "Excalibur")
hero
print(f"{hero.name} wields {hero.weapon}")
print(f"Stats: Health={hero.health}, Strength={hero.strength}")
This will output:
Parzival wields Excalibur
Stats: Health=100, Strength=15
36.4 The __init__
Method and self
Let’s break down the special parts of our class:
- The
__init__
method is called automatically when we create a new warrior self
refers to the specific instance being createdself.name = name
stores the name parameter as an attribute of the instance
Here’s another example with default values:
class Mage:
def __init__(self, name, mana=100, spell="Magic Missile"):
self.name = name
self.mana = mana
self.spell = spell
# Create mages with and without default values
= Mage("Merlin") # Uses default mana and spell
merlin = Mage("Gandalf", mana=150, spell="Fireball")
gandalf
print(f"{merlin.name} knows {merlin.spell} and has {merlin.mana} mana")
print(f"{gandalf.name} knows {gandalf.spell} and has {gandalf.mana} mana")
This will output:
Merlin knows Magic Missile and has 100 mana
Gandalf knows Fireball and has 150 mana
36.5 Creating Multiple Classes
We can create different classes for different types of characters:
class Warrior:
def __init__(self, name, health=100, weapon="Sword"):
self.name = name
self.health = health
self.weapon = weapon
class Archer:
def __init__(self, name, arrows=20, bow_type="Longbow"):
self.name = name
self.arrows = arrows
self.bow_type = bow_type
# Create different types of characters
= Warrior("Lancelot", weapon="Arondight")
knight = Archer("Robin", arrows=30, bow_type="Elven Bow")
ranger
print(f"{knight.name} carries {knight.weapon}")
print(f"{ranger.name} has {ranger.arrows} arrows for their {ranger.bow_type}")
This will output:
Lancelot carries Arondight
Robin has 30 arrows for their Elven Bow
36.6 Practice Time: Create Your Classes
Now it’s your turn to create some classes! Try these challenges:
Create a
Potion
class that has attributes for name, healing_power, and cost.Make a
Spell
class with attributes for name, mana_cost, and damage.Design a
Quest
class that tracks a quest’s name, difficulty, and reward.
Here’s a starting point:
# Challenge 1: Potion Class
class Potion:
def __init__(self, name, healing_power, cost):
# Your code here
pass
# Challenge 2: Spell Class
class Spell:
# Your code here
pass
# Challenge 3: Quest Class
class Quest:
# Your code here
pass
# Test your classes by creating some objects!
36.7 Common Bugs to Watch Out For
As you begin creating classes, be wary of these common pitfalls:
Forgetting
self
: Always includeself
as the first parameter in__init__
and other methods.Name Conflicts: Don’t use the same name for a class attribute and a parameter:
class Wrong: = "Default" # Class attribute name def __init__(self, name): # Parameter shadows class attribute = name # Wrong! Should be self.name = name name
Missing Parentheses: When creating objects, don’t forget the parentheses:
= Warrior # Wrong! This assigns the class itself warrior = Warrior() # Correct! This creates an instance warrior
Case Sensitivity: Class names should start with a capital letter by convention:
class warrior: # Not recommended class Warrior: # Recommended
Attribute Access: You can’t access instance attributes before they’re created:
class Warrior: def __init__(self): print(self.health) # Error! health doesn't exist yet self.health = 100 # This creates the attribute
36.8 Conclusion and Further Resources
You’ve taken your first steps into the world of object-oriented programming with Python classes. You now know how to create your own types, give them attributes, and create objects from them.
To learn more about Python classes, check out these excellent resources:
Remember, classes are like magical forges where you create templates for the objects in your programs. Keep practicing, and soon you’ll be crafting complex and powerful objects with ease. In our next lesson, we’ll learn how to add behaviors to our objects using methods!