Methods

When you start programming in Python, you quickly encounter functions—those reusable blocks of code that perform specific tasks. But once you dive into object-oriented programming (OOP), you’ll learn about methods. Methods are a special kind of function, tightly bound to objects, and they are essential to making your Python code organized, modular, and powerful.

In this comprehensive lesson, we’ll explore what methods are, how they differ from functions, how to define and use them, and why they are so fundamental in Python programming.

What Are Methods?

Simply put, a method is a function that is associated with an object. In Python, everything is an object, and methods allow us to interact with and manipulate those objects. You can think of methods as “actions” that an object can perform or “behaviors” that belong specifically to the object’s type.

For example, if you have a string object, it comes with many built-in methods like .upper() or .split(). These methods internally operate on that particular string instance.

💡 Remember:

A method is just a function, but it’s always called on an object and can access or modify the object’s data.

How Methods Differ from Functions

At first glance, methods and functions might seem identical. Both are blocks of reusable code that can take input and return output. But their context and usage differ significantly.

Methods vs Functions
AspectFunctionsMethods
DefinitionStandalone blocks of codeFunctions bound to objects (usually inside classes)
Calling syntaxfunc()object.method()
Access to dataUsually no access to object’s internal dataCan access and modify the object’s attributes
Belong toGlobal or module-levelClass or instance

Understanding this difference is crucial as you progress to using classes and objects in Python.

Defining Methods Inside Classes

Methods are typically defined inside classes to describe the behaviors of objects created from those classes. Here’s the basic form of a method inside a class:

📌 Deep Dive: Defining a Simple Method

PYTHON
class Dog:
    def bark(self):
        print("Woof!")

Here, bark is a method defined inside the Dog class. Notice the first parameter self. This is a special convention in Python that refers to the instance of the class itself. It allows the method to access attributes and other methods on the same object.

Why Is self Important?

When you call a method on an object, Python automatically passes the object reference as the first argument to the method. By convention, we name this parameter self. It’s how methods know which object they are working with.

Without self, a method would not know or be able to interact with the specific instance of the class.

💡 Key point:

self is not a keyword, but a naming convention. You can name it differently, but it is highly discouraged.

Calling Methods on Objects

To use a method, you first need to create an instance (object) of the class, then call the method using dot notation:

📌 Deep Dive: Creating an Object and Calling a Method

PYTHON
class Dog:
    def bark(self):
        print("Woof!")

my_dog = Dog()   # Create an instance of Dog
my_dog.bark()   # Call the bark method on the instance
Output
Woof!

This example shows the typical flow: define a class, instantiate an object, then call methods on the object.

Using Methods to Access and Modify Object Attributes

Methods become truly useful when they manipulate or retrieve data stored in an object’s attributes. Let’s expand the Dog class to demonstrate this:

📌 Deep Dive: Methods with Attributes

PYTHON
class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def bark(self):
        print(f"{self.name} says Woof!")

    def birthday(self):
        self.age += 1
        print(f"Happy birthday {self.name}, you are now {self.age} years old!")

Here:

  • __init__ is a special method called a constructor, used to initialize new objects.
  • self.name and self.age are attributes—data stored inside the object.
  • bark uses the attribute name to personalize output.
  • birthday modifies the age attribute to simulate aging.

📌 Deep Dive: Working with Attributes and Methods

PYTHON
my_dog = Dog("Rex", 3)
my_dog.bark()
my_dog.birthday()
my_dog.birthday()
Output
Rex says Woof! Happy birthday Rex, you are now 4 years old! Happy birthday Rex, you are now 5 years old!

This example highlights how methods provide controlled ways to interact with an object’s internal state.

Types of Methods in Python Classes

Besides regular instance methods (the ones we’ve seen so far), Python supports two other important method types:

  • Class methods — Methods that work with the class itself rather than an instance. They receive the class as the first argument (conventionally named cls).
  • Static methods — Methods that don’t access instance or class data; they behave like regular functions defined inside a class namespace.

Let’s look at each of them.

Class Methods

Use the @classmethod decorator to define a class method. They can be used, for example, to create factory methods or to maintain state shared across all instances.

📌 Deep Dive: Class Method Example

PYTHON
class Dog:
    species = "Canis familiaris"  # Class attribute

    def __init__(self, name):
        self.name = name

    @classmethod
    def common_species(cls):
        print(f"All dogs belong to the species {cls.species}")

Dog.common_species()  # Called on the class itself
Output
All dogs belong to the species Canis familiaris

Static Methods

Static methods don’t receive self or cls automatically. They behave like normal functions but belong logically inside the class for organization.

📌 Deep Dive: Static Method Example

PYTHON
class Dog:
    @staticmethod
    def info():
        print("Dogs are domesticated mammals.")

Dog.info()  # Call static method on class
Output
Dogs are domesticated mammals.

Notice that neither self nor cls is required or passed.

Calling Methods: Summary

Here is a quick rundown of how you call methods depending on their type:

  • Instance methods: Called on an instance (object). Python passes the instance as self.
  • Class methods: Called on the class. Python passes the class as cls.
  • Static methods: Called on the class (or instance), no automatic arguments are passed.

Method Naming Conventions and Best Practices

Some important tips to keep your methods clear and maintainable:

  • Use descriptive names that clearly indicate what the method does.
  • Follow Python’s snake_case style for method names.
  • Keep methods focused on a single responsibility.
  • Use self as the first parameter for instance methods.
  • Use decorators @classmethod and @staticmethod appropriately.

Built-in Methods: The Power You Already Have

Python’s standard library classes come with many built-in methods. For example, strings have methods like:

  • .lower() and .upper() to change case
  • .strip() to remove whitespace
  • .replace() to swap substrings
  • .split() to split into lists

These methods are invoked on string objects and operate specifically on those instances.

📌 Deep Dive: String Methods

PYTHON
text = "  Hello, World!  "
print(text.strip())
print(text.upper())
Output
Hello, World! HELLO, WORLD!

Understanding Method Resolution

When you call a method on an object, Python looks it up on that object’s class and its inheritance chain. This mechanism is called method resolution order (MRO). It allows subclasses to override or extend methods defined in parent classes.

We won’t dive deep into inheritance here, but keep this in mind as you work with more complex class hierarchies.

Architecture of Methods
Architecture of Methods

Practical Example: Building a Simple Bank Account Class

Let’s put what we learned into practice by creating a BankAccount class with methods to deposit, withdraw, and check the balance.

📌 Deep Dive: BankAccount Class with Methods

PYTHON
class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = balance

    def deposit(self, amount):
        if amount > 0:
            self.balance += amount
            print(f"Added ${amount} to the balance.")
        else:
            print("Deposit amount must be positive.")

    def withdraw(self, amount):
        if amount > self.balance:
            print("Insufficient funds!")
        elif amount <= 0:
            print("Withdrawal amount must be positive.")
        else:
            self.balance -= amount
            print(f"Withdrew ${amount} from the account.")

    def get_balance(self):
        return self.balance

Now let’s create an account and interact with it using methods:

📌 Deep Dive: Using the BankAccount Methods

PYTHON
acct = BankAccount("Alice", 100)
acct.deposit(50)
acct.withdraw(75)
print(f"Current balance: ${acct.get_balance()}")
Output
Added $50 to the balance. Withdrew $75 from the account. Current balance: $75

This example demonstrates how methods encapsulate functionality and protect the internal state of objects.

⚠️ Avoid Common Pitfall

Never forget to include self as the first parameter in instance methods. Omitting it will cause errors because Python won’t pass the instance automatically.

Summary

  • Methods are functions bound to objects, allowing interaction with specific instances.
  • The first parameter of instance methods is self, referring to the instance.
  • Methods can access and modify object attributes, encapsulating behavior.
  • Class methods receive the class itself as the first argument and are decorated with @classmethod.
  • Static methods are general functions inside a class namespace, decorated with @staticmethod.
  • Methods are called using dot notation on instances or on classes, depending on the method type.

Mastering methods is a key step towards effective Python programming and object-oriented design. Practice creating classes with methods, and explore how Python’s built-in types use methods to provide rich functionality.