Last modified: Feb 10, 2026 By Alexander Williams

Python Object Attributes Guide for Beginners

Python is an object-oriented programming language. Everything in Python is an object. Objects have attributes. Attributes are data stored inside objects.

Understanding attributes is key to mastering Python. This guide explains object attributes in detail. We will cover different types of attributes. We will also show you how to work with them.

What Are Python Object Attributes?

Attributes are variables that belong to an object. They define the object's state. Think of them as the object's properties or characteristics.

For example, a Dog object might have attributes like name, breed, and age. These attributes hold specific values for each dog.

Attributes are accessed using the dot (.) operator. This is a fundamental concept in Python's object model.

Defining Attributes in a Class

Attributes are typically defined inside a class. A class is a blueprint for creating objects. The __init__ method is a special constructor.

It runs when a new object is created. This is where you usually set initial attribute values.


class Dog:
    # The __init__ method initializes new objects
    def __init__(self, name, breed):
        # 'self' refers to the instance being created
        self.name = name   # Instance attribute
        self.breed = breed # Instance attribute
        self.age = 1       # Setting a default value

# Creating an instance of the Dog class
my_dog = Dog("Rex", "German Shepherd")

# Accessing attributes with the dot operator
print(my_dog.name)
print(my_dog.breed)
print(my_dog.age)
    

Rex
German Shepherd
1
    

In this example, name, breed, and age are instance attributes. They belong to the specific object my_dog.

For a deeper dive into creating objects, see our Python Objects: Classes, Instances, and Methods Guide.

Types of Object Attributes

Python has several types of attributes. The main ones are instance attributes and class attributes.

Instance Attributes

Instance attributes are unique to each object. They are defined inside methods, usually __init__. Their values can differ from one object to another.


dog1 = Dog("Buddy", "Golden Retriever")
dog2 = Dog("Molly", "Beagle")

dog1.age = 3
dog2.age = 5

print(f"{dog1.name} is {dog1.age} years old.")
print(f"{dog2.name} is {dog2.age} years old.")
    

Buddy is 3 years old.
Molly is 5 years old.
    

Changing dog1.age does not affect dog2.age. They are independent.

Class Attributes

Class attributes are shared by all instances of a class. They are defined directly under the class header, outside any method.


class Dog:
    # This is a class attribute
    species = "Canis familiaris"

    def __init__(self, name):
        self.name = name # Instance attribute

dog_a = Dog("Charlie")
dog_b = Dog("Daisy")

# Accessing a class attribute
print(dog_a.species)
print(dog_b.species)
print(Dog.species) # Also accessible via the class itself
    

Canis familiaris
Canis familiaris
Canis familiaris
    

If you change a class attribute, it changes for all instances. This is because they all share the same reference.

Dynamic Attributes and the setattr Function

Python is dynamic. You can add attributes to an object after it's created. This is not common but is possible.

You can use simple assignment or the built-in setattr function.


my_dog = Dog("Rex", "Husky")
# Adding a new attribute dynamically
my_dog.color = "Gray"
print(my_dog.color)

# Using the setattr() function
setattr(my_dog, 'favorite_toy', 'Frisbee')
print(my_dog.favorite_toy)
    

Gray
Frisbee
    

The setattr function takes three arguments: the object, the attribute name (as a string), and the value. It is useful for dynamic programming.

To get an attribute's value dynamically, use the getattr function. It can also provide a default value if the attribute doesn't exist.

Checking and Managing Attributes

You often need to check if an object has a specific attribute. Use the hasattr function for this.


print(hasattr(my_dog, 'name'))     # True
print(hasattr(my_dog, 'owner'))    # False

# Safe access with getattr and a default
owner = getattr(my_dog, 'owner', 'Unknown')
print(f"Owner: {owner}")
    

True
False
Owner: Unknown
    

To see all attributes of an object, use the built-in vars function or the __dict__ property.


print(vars(my_dog))
# Or equivalently:
print(my_dog.__dict__)
    

{'name': 'Rex', 'breed': 'Husky', 'age': 1, 'color': 'Gray', 'favorite_toy': 'Frisbee'}
{'name': 'Rex', 'breed': 'Husky', 'age': 1, 'color': 'Gray', 'favorite_toy': 'Frisbee'}
    

Note:__dict__ only shows instance attributes, not class attributes.

When objects become complex, you might use Python Objects in Objects: Nested Data Guide to manage them.

Private Attributes (Name Mangling)

Python does not have truly private attributes. However, a convention exists. Prefix an attribute name with a double underscore (__).

This triggers name mangling. Python changes the name internally to make it harder to access accidentally from outside the class.


class BankAccount:
    def __init__(self, owner, balance):
        self.owner = owner
        self.__balance = balance  # "Private" attribute

    def show_balance(self):
        # Can be accessed inside the class
        return self.__balance

account = BankAccount("Alice", 1000)
print(account.owner)
# print(account.__balance) # This would cause an AttributeError
print(account.show_balance())

# The mangled name (not recommended to use directly)
print(account._BankAccount__balance)
    

Alice
1000
1000
    

Name mangling is a weak internal signal. It is not a security feature. It helps prevent name clashes in inheritance.

Properties: Controlled Attribute Access

Sometimes you need more control over an attribute. You might want to validate data or compute a value on the fly.

Use the @property decorator. It lets you define a method that can be accessed like an attribute.


class Circle:
    def __init__(self, radius):
        self.radius = radius

    @property
    def diameter(self):
        # Calculated when accessed
        return self.radius * 2

    @property
    def area(self):
        import math
        return math.pi * (self.radius ** 2)

my_circle = Circle(5)
# Access like an attribute, not a method call
print(f"Radius: {my_circle.radius}")
print(f"Diameter: {my_circle.diameter}")
print(f"Area: {my_circle.area:.2f}")
    

Radius: 5
Diameter: 10
Area: 78.54
    

Properties are powerful. They provide a clean interface. They can also have setter methods (@diameter.setter) to control assignment.

Common Pitfalls with Attributes

Beginners often confuse class and instance attributes. Modifying a mutable class attribute (like a list) can have unexpected side effects.


class Warehouse:
    inventory = []  # Class attribute (mutable list)

    def __init__(self, location):
        self.location = location
        self.inventory.append(location) # Modifies shared list

wh1 = Warehouse("NYC")
wh2 = Warehouse("LA")
print(Warehouse.inventory) # Affects all instances!
    

['NYC', 'LA']
    

To avoid this, initialize mutable attributes inside __init__. This ensures each instance gets its own separate list.

Another pitfall is typos when accessing attributes. This leads to AttributeError. Use hasattr to check first if you are unsure.

Conclusion

Python object attributes are fundamental. They store data that defines an object's state. You learned about instance and class attributes.

You saw how to define, access, and manage them. You explored dynamic attributes with setattr and getattr.

You also learned about private attributes and properties. Remember the difference between class and instance attributes.

This knowledge is crucial for effective object-oriented programming in Python. Practice creating classes and manipulating attributes.

When you need to save or share your objects, understanding attributes will help with JSON serialization.