python class attributes instance attributes init method variables

difference between variables inside and outside of __init__ class and instance attributes

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In Python, variables written directly in the class body are usually class attributes, while values assigned to self inside __init__ are instance attributes. The difference matters because class attributes are shared across instances, but instance attributes belong to each object separately.

A related point is easy to miss: a plain variable created inside __init__ without self is only a local variable. It disappears when __init__ finishes.

Class Attributes Live On The Class

A class attribute is defined in the class body:

python
class User:
    role = "member"

Every instance can read role:

python
1u1 = User()
2u2 = User()
3
4print(u1.role)
5print(u2.role)
6print(User.role)

All three lookups refer to the same shared class-level value unless an instance later shadows it with its own attribute.

Class attributes are a good fit for constants, metadata, and shared defaults that should be the same across objects.

Instance Attributes Live On Each Object

Instance attributes are usually created inside __init__ with self:

python
class User:
    def __init__(self, name):
        self.name = name

Now each object stores its own value:

python
1u1 = User("Alice")
2u2 = User("Bob")
3
4print(u1.name)
5print(u2.name)

Changing u1.name does not affect u2.name because the attribute belongs to the specific instance.

Local Variables Inside __init__

A variable inside __init__ is not automatically an attribute. It becomes an instance attribute only if you attach it to self.

python
1class Demo:
2    def __init__(self):
3        local_value = 10
4        self.instance_value = 20

After construction, local_value is gone. Only instance_value remains on the object.

This is one of the most common beginner confusions: location inside __init__ does not matter by itself. The key is whether the value is assigned to self.

How Attribute Lookup Works

Python looks for attributes on the instance first and then on the class. That means a class attribute can be shadowed by an instance attribute with the same name:

python
1class User:
2    role = "member"
3
4u = User()
5print(u.role)
6
7u.role = "admin"
8print(u.role)
9print(User.role)

After u.role = "admin", the object has its own role attribute. User.role remains unchanged, but u.role now resolves to the instance-level value.

This lookup order explains many situations that seem mysterious at first. The same rule is why assigning through the class changes the shared value, while assigning through one instance affects only that instance unless the attribute was never shadowed.

The Mutable Class Attribute Trap

The most important practical bug is putting mutable state on the class when you intended each object to have its own copy:

python
class Team:
    members = []

Then:

python
1t1 = Team()
2t2 = Team()
3
4t1.members.append("Alice")
5print(t2.members)

t2.members now also contains Alice because both instances share the same class-level list. The correct pattern is:

python
class Team:
    def __init__(self):
        self.members = []

Now each object gets an independent list.

Common Pitfalls

The biggest mistake is storing mutable per-object state as a class attribute. That creates accidental sharing across instances.

Another pitfall is assuming a variable inside __init__ becomes an attribute automatically. Unless it is assigned to self, it is only a local variable.

A third issue is forgetting about Python's lookup order. When obj.attr works, Python may be reading a class attribute because no instance attribute exists yet.

Summary

  • Values defined in the class body are usually class attributes.
  • Values assigned to self inside __init__ are instance attributes.
  • Plain local variables inside __init__ disappear after initialization.
  • Python checks instance attributes first and class attributes second.
  • Mutable data usually belongs on the instance, not on the class.

Course illustration
Course illustration

All Rights Reserved.