Data and behavior
Attributes hold what an object knows. Methods describe what it can do. A method is a function defined inside a class, and it is called on an object with the dot operator, as in rex.bark(). This is the second half of object-oriented design: data and behavior living together.
Defining a method and the self parameter
You define a method with def inside the class body. Its first parameter is always self:
class Dog:
def __init__(self, name):
self.name = name
def bark(self):
print("Woof! I am " + self.name)
When you call rex.bark(), Python passes rex in as self. You write no argument for it. Inside the method, self is how you reach the object's own data: self.name is the name of the dog the method was called on. That is why two dogs can use the same method and print different names.
rex = Dog("Rex")
luna = Dog("Luna")
rex.bark()
luna.bark()
Woof! I am Rex
Woof! I am Luna
There is no magic here. rex.bark() is shorthand for Dog.bark(rex), which also works and prints the same line. Seeing that form makes it clear why the method needs a self parameter: it is the first argument of an ordinary function.
Methods can change the object
Because a method receives the object, it can also assign to its attributes:
class Dog:
def __init__(self, name):
self.name = name
def rename(self, new_name):
self.name = new_name
rex = Dog("Rex")
rex.rename("Max")
print(rex.name)
Max
Any parameters after self are the ones you pass when calling: rename("Max") supplies new_name.
Methods can call other methods
Since self is the object, a method can use it to call the object's other methods and to read another object's attributes if one is passed in:
class Dog:
def __init__(self, name):
self.name = name
def bark(self):
print("Woof! I am " + self.name)
def greet(self, other):
print("Hello, " + other.name)
self.bark()
Dog("Rex").greet(Dog("Luna"))
Hello, Luna
Woof! I am Rex
Notice that greet calls self.bark() and not just bark(). A method is looked up on an object, so the call needs the object in front of it.
The lesson's exercise
The starter code already has the class with its __init__, and at the bottom it creates rex = Dog("Rex") and calls rex.bark(). The class is missing the method.
- Declare the method. Below
__init__, inside the class and at the same indentation, writedef bark(self):. Onlyselfis needed, because the call passes no other arguments. - Write the body. Indent one level further and print
"Woof! I am "joined withself.name. Both parts are strings, so+joins them directly.
Writing just name instead of self.name would not work. The attribute belongs to the object, and a bare name is a separate variable that does not exist inside the method. The complete program:
class Dog:
def __init__(self, name):
self.name = name
def bark(self):
print("Woof! I am " + self.name)
rex = Dog("Rex")
rex.bark()
Woof! I am Rex
How a method differs from a function
A method is written with the same def as any function. The difference is where it lives and how it is reached. A function stands alone and you pass it everything it needs. A method sits inside a class, so Python can hand it the object it was called on. A class can hold as many methods as it needs, and they all see the same object through self.
Common mistakes
Leaving out self
If you define def bark(): with no parameter, the call rex.bark() still passes the object, and Python complains:
TypeError: Dog.bark() takes 0 positional arguments but 1 was given
The count in the message includes the self that Python passed silently, which is why it can look confusing.
Passing self yourself
Calling rex.bark(rex) gives the method two arguments when it expects one, and fails with a TypeError. Python supplies self for you.
Printing versus returning
The bark method prints its text, so calling it produces output but gives back None. If you wanted the text itself, to store it or use it in other code, you would write return instead of print. Methods can do both, but they are different things.
Wrong indentation
A method must be indented inside the class. If def bark(self): sits at the left margin, it is an ordinary function outside the class, and rex.bark() raises an AttributeError.
Key takeaways
- A method is a function defined inside a class, called on an object.
- Its first parameter is
self, the object the method was called on. Python passes it automatically. - Inside a method, use
self.nameto read or change the object's attributes. - Parameters after
selfare the arguments you pass in the call.