Okay, we've seen how classes act as blueprints and how attributes store the specific data or state for each object created from that blueprint. For instance, a Dog
class might define that dogs have a name
and a breed
, and each individual Dog
object would hold its specific name and breed in its attributes.
But objects aren't just passive containers for data. They often need to do things or have actions performed on them. A dog can bark, a car can drive, a bank account can have money deposited into it. In Object-Oriented Programming, these actions or behaviors are defined using methods.
Think of methods as functions that "belong" to a class. They are defined inside the class block, just like attributes, but they use the familiar def
keyword we learned about when creating standalone functions.
Let's add a behavior to our Dog
class. We want any Dog
object to be able to "speak".
class Dog:
# The __init__ method initializes the object's attributes
def __init__(self, name, breed):
self.name = name
self.breed = breed
print(f"Dog initialized: {self.name}")
# This is a method: a function defined inside a class
def bark(self):
print(f"{self.name} says Woof!")
# Create an instance (object) of the Dog class
my_dog = Dog("Buddy", "Golden Retriever")
# Call the bark method on the my_dog object
my_dog.bark()
If you run this code, you'll see:
Dog initialized: Buddy
Buddy says Woof!
Notice the bark
function defined inside the Dog
class. This is a method.
self
Parameter: Referring to the Object ItselfYou probably noticed the self
parameter in both __init__
and bark
. What is that?
When you define a method inside a class, the first parameter of that method always receives a reference to the instance (the specific object) on which the method was called. By convention, this parameter is almost always named self
.
Look at the bark
method again:
def bark(self):
print(f"{self.name} says Woof!")
Inside bark
, we use self.name
. This tells Python: "Access the name
attribute of the specific object that this bark
method was called on."
When we write my_dog.bark()
, Python automatically passes the my_dog
object as the first argument to the bark
method. So, inside the method call, self
is my_dog
. That's how the method knows which dog's name to print.
You don't explicitly pass self
when you call the method (my_dog.bark()
, not my_dog.bark(my_dog)
). Python handles this automatically for you. However, you must include self
as the first parameter when you define the method within the class.
Methods are the primary way you interact with an object's data (its attributes). They can read attribute values, as seen in the bark
method, and they can also change them.
Let's add a method to change the dog's name:
class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed
print(f"Dog initialized: {self.name}")
def bark(self):
print(f"{self.name} says Woof!")
# Method to change the dog's name attribute
def set_name(self, new_name):
if isinstance(new_name, str) and new_name: # Basic check
self.name = new_name
print(f"My name has been changed to {self.name}")
else:
print("Please provide a valid name.")
# Create instances
dog1 = Dog("Buddy", "Golden Retriever")
dog2 = Dog("Lucy", "Beagle")
# Use the methods
dog1.bark() # Output: Buddy says Woof!
dog2.bark() # Output: Lucy says Woof!
print(f"Dog 1's name is currently: {dog1.name}") # Output: Dog 1's name is currently: Buddy
# Call the set_name method on dog1
dog1.set_name("Max") # Output: My name has been changed to Max
print(f"Dog 1's name is now: {dog1.name}") # Output: Dog 1's name is now: Max
dog1.bark() # Output: Max says Woof!
In the set_name
method:
self
(the specific Dog
object) and new_name
(the desired new name).new_name
is a non-empty string.name
attribute using self.name = new_name
.dog1.set_name("Max")
only changes the name of dog1
. The dog2
object remains unaffected because self
inside that specific method call referred to dog1
.It's helpful to think of methods as functions associated with objects. The main difference is that methods operate within the context of an object (via self
) and can directly access and manipulate that object's attributes. Standalone functions don't have this inherent connection to an object's state.
By bundling data (attributes) and behavior (methods) together in classes, OOP helps you create more organized, reusable, and understandable code, especially as your programs grow larger. You're modeling components of your problem as objects that know things (attributes) and can do things (methods).
© 2025 ApX Machine Learning