Python Class Properties
Class Properties
Properties (also called attributes) are the variables that store data in a class or its objects. A Phone object might have a brand and a price; a User object might have a name and points.
Python has two kinds of properties:
- Instance properties — belong to an individual object; each object has its own value.
- Class properties — belong to the class itself; one value is shared by all objects.
This lesson covers how to define, access, modify, add, and delete properties, and how the two kinds differ.
Terminology note: In everyday tutorials, "property" and "attribute" are used interchangeably. Python also has a specific feature called
@property(shown briefly at the end of this lesson), which turns a method into a managed attribute.
Defining Instance Properties
Most properties are defined inside the __init__() method using self. Because they belong to each individual object, they are called instance properties.
Example: A Class With Properties
class Employee:
def __init__(self, emp_id, salary):
self.emp_id = emp_id
self.salary = salary
e1 = Employee(101, 45000)
print(e1.emp_id)
print(e1.salary)
Expected output:
101
45000
self.emp_id = emp_id creates an emp_id property on the new object and stores the argument in it.
Accessing Object Properties
Properties are accessed with dot notation:
object_name.property_name
Example: Accessing Properties
class Phone:
def __init__(self, brand, price):
self.brand = brand
self.price = price
p1 = Phone("Samsung", 30000)
print(p1.brand)
print(p1.price)
Expected output:
Samsung
30000
Accessing a property that does not exist raises an error:
print(p1.color)
Output:
AttributeError: 'Phone' object has no attribute 'color'
To read a property that might not exist, use getattr() with a default: getattr(p1, "color", "Unknown") returns "Unknown".
Modifying Properties
Object properties can be updated after the object is created, by assigning a new value.
Example: Updating a Property
class User:
def __init__(self, name, points):
self.name = name
self.points = points
u1 = User("Amit", 80)
print(u1.points)
u1.points = 95
print(u1.points)
Expected output:
80
95
Only u1 changes. Other User objects keep their own points values.
Best practice: Changing properties directly is simple, but it bypasses any validation. For data that must follow rules (for example, points that can never be negative), update it through a method instead. This idea is developed in the Encapsulation lesson.
Deleting Properties
Remove a property from an object with del.
Example: Deleting a Property
class Player:
def __init__(self, username, level):
self.username = username
self.level = level
p1 = Player("Neo", 7)
del p1.level
print(p1.username)
print(p1.level)
Output:
Neo
AttributeError: 'Player' object has no attribute 'level'
After del p1.level, the level property no longer exists on p1, so accessing it raises an AttributeError. Other Player objects still have their own level. Deleting properties is rarely needed in practice.
Class Properties vs Instance Properties
| Instance Property | Class Property | |
|---|---|---|
| Where it is defined | Inside a method, usually __init__(), using self. | Directly in the class body |
| Belongs to | Each individual object | The class |
| Shared between objects | No — each object has its own value | Yes — one value for all objects |
| Typical use | Data that differs per object (name, price) | Data common to all objects (category, tax rate) |
Example: Class and Instance Properties Together
class Animal:
category = "Mammal" # Class property
def __init__(self, name):
self.name = name # Instance property
a1 = Animal("Dog")
a2 = Animal("Cat")
print(a1.name)
print(a2.name)
print(a1.category)
print(a2.category)
Expected output:
Dog
Cat
Mammal
Mammal
nameis different for each object.categoryis defined once in the class and shared by both objects.
How Python Finds a Property
When you access a1.category, Python looks in two places, in this order:
- The object itself — does
a1have its owncategory? - The class — does
Animalhave acategory?
Because a1 has no category of its own, Python finds it on the class.
Modifying Class Properties
Changing a class property through the class affects every object that does not have its own value.
Example: Updating a Class Property
class Company:
country = "India"
def __init__(self, name):
self.name = name
c1 = Company("TechSoft")
c2 = Company("InnoLabs")
Company.country = "USA"
print(c1.country)
print(c2.country)
Expected output:
USA
USA
Both objects read country from the class, so both see the new value.
Caution: Assigning Through an Object Creates an Instance Property
Assigning to a class property through an object does not change the class. It creates a new instance property on that object only:
c1 = Company("TechSoft")
c2 = Company("InnoLabs")
c1.country = "Singapore"
print(c1.country)
print(c2.country)
print(Company.country)
Expected output:
Singapore
India
India
c1 now has its own country, which hides the class property for c1 only. To change a shared value, always assign through the class name: Company.country = ....
Practical Use: Counting Objects
A class property can track information about all instances, such as how many have been created:
class Ticket:
issued = 0
def __init__(self, passenger):
self.passenger = passenger
Ticket.issued += 1
t1 = Ticket("Asha")
t2 = Ticket("Ravi")
print("Tickets issued:", Ticket.issued)
Expected output:
Tickets issued: 2
Inside __init__(), Ticket.issued += 1 updates the shared counter through the class name.
Caution: Mutable Class Properties
A list or dictionary defined as a class property is shared by all objects. Changing it through one object changes it for all:
class Team:
members = [] # Shared by every Team object!
t1 = Team()
t2 = Team()
t1.members.append("Asha")
print(t2.members)
Expected output:
['Asha']
For per-object lists, create them in __init__() instead: self.members = [].
Adding New Properties to Objects
Python lets you add new properties to an object at any time, even after it was created.
Example: Adding Properties at Runtime
class Customer:
def __init__(self, name):
self.name = name
c1 = Customer("Rahul")
c1.email = "rahul@example.com"
c1.balance = 1200
print(c1.name)
print(c1.email)
print(c1.balance)
Expected output:
Rahul
rahul@example.com
1200
These new properties exist only on c1. Another Customer object would not have email or balance.
Best practice: Adding properties outside the class works, but it makes objects of the same class inconsistent and is easy to misspell. Define all expected properties in
__init__()— usingNonefor values that are not known yet — so every object has the same structure.
Viewing All Properties of an Object
Every object stores its instance properties in a dictionary called __dict__:
class Customer:
def __init__(self, name):
self.name = name
c1 = Customer("Rahul")
c1.balance = 1200
print(c1.__dict__)
Expected output:
{'name': 'Rahul', 'balance': 1200}
Class properties are not included, because they belong to the class, not the object. The built-in vars(c1) returns the same dictionary.
A Brief Look at @property
Python's @property decorator lets you define a method that is accessed like an attribute — useful for calculated values or controlled access:
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
@property
def area(self):
return self.width * self.height
r = Rectangle(4, 5)
print(r.area)
Expected output:
20
r.area is written without parentheses, but it calls the area() method each time, so the value is always up to date. @property is explored further in the Encapsulation lesson.
Common Mistakes
| Mistake | Problem |
|---|---|
| Accessing a property that was never set | AttributeError |
Changing a shared value through an object (obj.rate = 5) | Creates an instance property instead of changing the class |
| Using a list as a class property for per-object data | All objects share and modify the same list |
Misspelling a property when assigning (u1.ponts = 95) | Silently creates a new property |
Adding properties outside __init__() | Objects of the same class have inconsistent structure |
Related Concepts
- Python
__init__()Method — where instance properties are usually created - Python self Parameter — how methods access properties
- Python Class Methods — behavior that works with properties
- Python Encapsulation — protecting properties from invalid changes