What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
A Python class is a blueprint for a new type. Calling the class creates an instance, each instance can hold its own data as attributes, and functions defined inside the class become methods you call on those instances. The concept becomes much easier once you separate what belongs to the class itself from what belongs to each individual object.
What a class creates
The official Python Tutorial puts the purpose in one sentence: “Classes provide a means of bundling data and functionality together.” (Python Tutorial, “9. Classes”, Python Software Foundation). A class groups related data and behavior under one name, and it defines a new type.
As an Amazon Associate I earn from qualifying purchases.
Consider a small class that describes dogs:
class Dog:
pass
fido = Dog()
print(type(fido)) # <class '__main__.Dog'>
The class Dog is the definition. Calling Dog() produces an instance (also called an object), and fido refers to that one particular dog. You can create as many instances as you need from the same class, and each is a separate object.
Attributes: values attached to an object
An attribute is a name accessed with a dot. Once a value is attached to an object, you read it the same way every time:
#1 Best Overall
fido.name = "Fido"
print(fido.name) # Fido
Attributes are how an object carries its state. Assigning fido.name does not change any other dog; a second instance can hold a different value under the same attribute name.
Methods and self
A method is a function defined inside a class. When you access it through an instance, Python supplies that instance as the first argument. The parameter is conventionally named self, but that name has no special status in the language; it is a convention that every Python programmer recognizes.
class Dog:
def bark(self):
print(f"{self.name} says woof")
fido = Dog()
fido.name = "Fido"
fido.bark() # Fido says woof
The call fido.bark() is equivalent to Dog.bark(fido). Inside the method, self refers to whichever instance the method was called on, which is why the same method can print different names for different dogs.
Rank #2
The __init__ method sets up each new instance
__init__ is called to initialize a newly created instance. It is the usual place to assign per-instance attributes, so every object starts with the state it needs:
class Dog:
def __init__(self, name):
self.name = name
fido = Dog("Fido")
buddy = Dog("Buddy")
print(fido.name, buddy.name) # Fido Buddy
The Python Tutorial uses the same pattern in its own examples, where values passed to the constructor are stored on self (Python Tutorial, “9. Classes”). Note that __init__ runs after the object already exists; its job is to set that object up, not to create it.
Class attributes versus instance attributes
Attributes can also live on the class itself. Here kind is defined once for all dogs:
class Dog:
kind = "canine"
def __init__(self, name):
self.name = name
fido = Dog("Fido")
buddy = Dog("Buddy")
print(fido.kind, buddy.kind) # canine canine
Lookup starts at the instance and falls back to the class, so both dogs see the shared value. Assigning to the attribute through one instance creates a new instance attribute that shadows the class value. It does not modify the class:
fido.kind = "wolf"
print(fido.kind) # wolf
print(buddy.kind) # canine
print(Dog.kind) # canine
del fido.kind # remove the shadowing instance attribute
print(fido.kind) # canine again
To change the value for every dog, assign it on the class: Dog.kind = "canid".
| Question | Class attribute | Instance attribute |
|---|---|---|
| Where is the value stored? | On the class | On the individual object |
| Do instances share it? | Yes, through lookup, unless an instance shadows it | No, each instance has its own value |
| Typical assignment location | In the class body | Usually in __init__ as self.name |
| Effect of assigning through an instance | Creates an instance attribute that hides the class value | Changes only that object |
| Good for | Values that are the same for every object, such as a species label | State that differs per object, such as a name |
The mutable class data trap
Shared class data becomes a real problem when it is mutable, such as a list. The tutorial illustrates this with a tricks list defined on the class. Both dogs see the same list:
class Dog:
tricks = [] # class attribute: shared
def __init__(self, name):
self.name = name
def add_trick(self, trick):
self.tricks.append(trick) # mutates the shared list
a = Dog("Fido")
b = Dog("Buddy")
a.add_trick("roll over")
print(b.tricks) # ['roll over'] -- Buddy got Fido's trick
self.tricks.append(...) does not create an instance attribute; it finds the class list and changes it in place. The fix is to give each dog its own list in __init__:
class Dog:
def __init__(self, name):
self.name = name
self.tricks = [] # a new list for each instance
def add_trick(self, trick):
self.tricks.append(trick)
a = Dog("Fido")
b = Dog("Buddy")
a.add_trick("roll over")
print(b.tricks) # []
The rule of thumb: if a value should belong separately to every object and it is mutable, assign it in __init__.
Recommended Free Tools
Privacy in Python is a convention
Python does not enforce private instance attributes. The official Python Tutorial notes that private instance variables that cannot be accessed except from inside the object do not exist in Python. Two naming conventions exist instead:
Best Value
- A single leading underscore (
self._cache) signals that a name is non-public. Other programmers are expected to respect it, but Python does not block access. - A double leading underscore (
self.__token) triggers name mangling. Insideclass Dog,__tokenis stored as_Dog__token. The purpose is mainly to reduce accidental name collisions with subclasses, not to secure data.
For the object model more broadly, the official Python Programming FAQ is a useful companion reference.
Terms to keep straight
- Class: the definition used to create instances.
- Instance or object: one value created from a class.
- Attribute: a name accessed with a dot, such as
dog.name. - Method: a function defined in a class that receives the instance as its first argument.
- Class variable or class attribute: data attached to the class, potentially shared by all its instances.
- Instance variable or instance attribute: data attached to one object.
When you read Python code, check first whether a name is assigned in the class body or on self. That single distinction explains most surprises about shared state.
Once these pieces are clear, the next topics to study are inheritance and the object model details that build on them.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsQuick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




