Skip to content
beginner

Attributes and Methods in Python Classes

A class is a blueprint, but the blueprint is not the point. The point is what happens when you build real objects from it—each one carrying its own facts…

Published 2026-09-05Updated 2026-09-127 min read
A sleek and contemporary library interior, showcasing modern architectural design and ample natural lighting.
A sleek and contemporary library interior, showcasing modern architectural design and ample natural lighting. Photo by Marcus Lenk on Pexels.

A class is a blueprint, but the blueprint is not the point. The point is what happens when you build real objects from it—each one carrying its own facts and able to take its own actions. Those facts are attributes. Those actions are methods. Once this distinction clicks, reading Python code gets dramatically easier.

What Attributes and Methods Actually Are

A central Python class branches to two separate BankAccount objects. Each object contains its own owner and balance attributes, while shared methods such as check_balance and deposit point to actions that read or change that object's balance. A separate class-level bank_name value is shown as shared by both objects.
A class provides the blueprint; each object keeps its own instance data while using methods to read or change that data. Class attributes can remain shared.

If you've worked through the basics of classes and objects, you know that a class is a template and an object is one instance built from that template. But what actually lives inside an instance?

Two kinds of things:

  • Attributes are the data an object stores—its facts. A bank account has a balance. A pet has a name. A user has an email address.
  • Methods are the actions an object can take—its behaviors. A bank account can accept a deposit. A pet can bark. A user can update their profile.

Think of it this way: attributes answer "what does this object know?" and methods answer "what can this object do?"

One quick clarification before we build: in Python, a method is technically an attribute too—a function attached to a class. But for everyday coding, it helps to treat them as two different jobs. An attribute is a named value. A method is a function you call with parentheses. This article focuses on regular instance methods, not the special @classmethod decorator you may see later.

Let's build one small example we'll use throughout this tutorial: a BankAccount class. Every account needs to remember its balance, and every account needs to be able to handle deposits and withdrawals.

Knowledge check

Check your understanding

Answer this question before you continue.

Which choice correctly describes the difference between an attribute and a method in the article's everyday coding model?
Single Choice

Focus: Distinguish an attribute from a method by whether it stores data or performs an action.

Instance Attributes: Data That Belongs to One Object

The most common kind of attribute is an instance attribute—data that belongs to a specific object, not to the class as a whole.

You define instance attributes inside a special method called __init__, which Python runs automatically when you create a new object. The first parameter, self, refers to the specific object being created.

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

Here, self.owner and self.balance are instance attributes. When you create two accounts, each one gets its own copy:

account_1 = BankAccount("Maya", 500)
account_2 = BankAccount("Diego", 1200)

print(account_1.owner, account_1.balance)
print(account_2.owner, account_2.balance)
Maya 500
Diego 1200

Notice what happened: both objects came from the same class, but each one stores different values. Maya's balance has nothing to do with Diego's balance. That's the whole point of instance attributes—they keep each object's state separate.

Why does this matter? Because in real programs, you'll have hundreds or thousands of objects at once. Two users, two accounts, two orders—each needs its own data without accidentally overwriting the others.

Knowledge check

Check your understanding

Answer this question before you continue.

What does this code print?
Output Prediction

Focus: Predict that separate objects retain separate values for instance attributes.

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

account_1 = BankAccount("Maya", 500)
account_2 = BankAccount("Diego", 1200)
account_1.balance = account_1.balance + 100
print(account_1.balance)
print(account_2.balance)

Methods: Actions an Object Can Take

A method is just a function defined inside a class. Like __init__, every regular method takes self as its first parameter, which lets it read and modify the object's own attributes.

Let's add two methods to our BankAccount class: one that reads the balance, and one that changes it.

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

    def check_balance(self):
        return self.balance

    def deposit(self, amount):
        self.balance = self.balance + amount
        return self.balance

The check_balance method reads self.balance and returns it. The deposit method updates self.balance by adding the deposit amount. You call methods using dot notation, just like accessing an attribute—but with parentheses at the end:

account = BankAccount("Maya", 500)
print(account.check_balance())
account.deposit(250)
print(account.check_balance())
500
750

The first call returns the original balance. The deposit changes the object's state, so the second call returns the new balance. The account remembered the change—that's the method working on the object's own data.

One note: self is a convention, not a Python keyword. You could name it anything, but every Python programmer expects self. Always use it.

Knowledge check

Check your understanding

Answer this question before you continue.

What does this code print?
Output Prediction

Focus: Trace a method call that updates an instance attribute and returns the updated value.

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

    def deposit(self, amount):
        self.balance = self.balance + amount
        return self.balance

account = BankAccount(400)
print(account.deposit(150))
print(account.balance)

Class Attributes: Data Shared by Every Object

Sometimes you want data that every object shares—not a per-object copy, but one value common to the whole class. That's a class attribute.

You define class attributes directly in the class body, outside any method:

class BankAccount:
    bank_name = "Python Savings Bank"

    def __init__(self, owner, balance):
        self.owner = owner
        self.balance = balance

Now bank_name belongs to the class itself. You can access it through the class name or through any instance:

print(BankAccount.bank_name)

account = BankAccount("Maya", 500)
print(account.bank_name)
Python Savings Bank
Python Savings Bank

Every account sees the same bank name. That's the key difference: instance attributes differ per object, while class attributes are shared across all objects of the class.

Class attributes work well for class-wide constants and configuration—values that genuinely should not differ from one object to the next.

Warning: Do not use a class attribute for a default value that objects will change, especially if that value is a list or dictionary. If one object modifies a shared mutable class attribute, every object sees the change. When an object needs its own changeable data, store it on self as an instance attribute.

Instance vs. Class Attributes: When to Use Each

The decision rule is simple:

  • Use an instance attribute when each object needs its own value.
  • Use a class attribute when every object should share the same value.
Instance AttributeClass Attribute
Where it's definedInside __init__ with selfDirectly in the class body
Who owns itOne specific objectThe class, shared by all objects
Use this whenEach object needs unique dataAll objects share one value
Exampleself.balance = balancebank_name = "Python Savings Bank"

There's one classic beginner trap worth knowing about. If you try to change a class attribute through one instance, Python doesn't update the shared value—it silently creates a new instance attribute that only affects that one object.

account_1 = BankAccount("Maya", 500)
account_2 = BankAccount("Diego", 1200)

account_1.bank_name = "Different Bank"
print(account_1.bank_name)
print(account_2.bank_name)
print(BankAccount.bank_name)
Different Bank
Python Savings Bank
Python Savings Bank

Maya's account now shows a different bank name, but Diego's account and the class itself still show the original. The assignment created a new instance attribute on account_1 that shadows the class attribute. If you genuinely need to change a class attribute, change it through the class name: BankAccount.bank_name = "New Name".

Knowledge check

Check your understanding

Answer this question before you continue.

A program needs every BankAccount object to use the same bank name. Where should that value be defined?
Misconception Check

Focus: Choose a class attribute when a value should be shared by every object.

Where This Shows Up in Real Code

This isn't just textbook theory. When you start using Python libraries, you'll constantly ask two questions about the objects you meet: which values are attributes, and which calls are methods?

A web framework's User object stores a name and email as attributes and has methods like save() or send_password_reset(). A data analysis tool's DataFrame stores rows and columns as attributes and has methods like mean() or dropna(). The same reading habit applies everywhere: check what the object knows, then check what it can do.

Your Practice Task

Here's your next move: build a BankAccount class from scratch with a balance attribute and deposit and withdraw methods. For withdraw, follow this decision rule: check the amount against the balance first, change self.balance only when the amount is valid, and leave the balance unchanged otherwise.

Create an account, deposit some money, withdraw some money, and print the balance after each step. Try withdrawing more than the balance and confirm the balance does not go negative.

Run it. Break it. Fix it. That's how this sticks. Once you're comfortable with attributes and methods, you're ready to move on to more advanced OOP concepts like inheritance—where classes build on other classes.

Knowledge check

Final check

Finish the article by checking the ideas you just learned.

What does this code print?
Question 1 of 2Output Prediction

Focus: Predict the effect of assigning a class-attribute name through one instance.

class BankAccount:
    bank_name = "Python Savings Bank"

account_1 = BankAccount()
account_2 = BankAccount()
account_1.bank_name = "Different Bank"
print(account_1.bank_name)
print(account_2.bank_name)
print(BankAccount.bank_name)
Which implementation follows the practice task's rule for a withdrawal that must not make the balance negative?
Question 2 of 2Debugging

Focus: Apply the article's rule for changing a balance only when a withdrawal is valid.

Assume amount is the requested withdrawal and self.balance is the current balance.

References

  1. 9. Classes — Python 3.14.7 documentationdocs.python.org
8sources checked
8source domains
5searches run

Research updated Sep 5, 2026

Practical resource

Want a more structured Python path?

Use the Python Starter Pack to turn scattered tutorials into a focused practice path.

View the bundle
Coming soon

Python Starter Pack

A compact LearnPyFast PDF pack covering what Python is, installation, your first program, running Python code, and Python versions.

$9
PDF BundleTopic PackPythonBeginner
  • 5 curated chapters
  • Enhanced PDF edition with bundle-only learning guidance
  • Offline-friendly format for focused review
  • Source article links for future online updates

Coming soon

Free Python bundle

Get the LearnPyFast Python Starter Bundle

A focused collection of beginner-friendly Python resources to help you move from setup to building practical projects.

You’ll receive the bundle by email. You can unsubscribe anytime.

No spam. You can unsubscribe anytime. See our Privacy policy.

Related sites

Continue beyond Python

Explore related Worldmonger sites when you want to move from Python basics into JavaScript or LLM application building.

JavaScript tutorialstutorial

LearnJSFast

Beginner-friendly JavaScript tutorials for practical web development and self-taught developers.

JavaScriptFrontendWeb development
Visit LearnJSFast
LLM tutorialstutorial

LearnLLMFast

Practical LLM tutorials for builders who want to understand prompting, workflows, agents, and AI applications.

LLMAIBuilders
Visit LearnLLMFast

Keep learning

Related tutorials

Continue with nearby Python topics and beginner-friendly explanations.