Class vs instance attributes

Class attributes and instance attributes are used to store data within a class. However, they have different scopes and behaviors.

**Class Attributes:**

Class attributes are attributes that are shared by all instances of a class. They are defined outside any method in the class and are the same for all objects of that class. Class attributes are accessed using the class name or any instance of the class.

Let's take an example of a `Car` class with a class attribute called `wheels`:

class Car:
    wheels = 4

    def __init__(self, make, model):
        self.make = make
        self.model = model
In this code, the `wheels` attribute is a class attribute. It is defined outside any method in the class and is shared by all instances of the `Car` class.

To access the class attribute, we can use the class name or any instance of the class:

print(Car.wheels)  # Output: 4

car1 = Car("Toyota", "Camry")
print(car1.wheels)  # Output: 4

car2 = Car("Honda", "Accord")
print(car2.wheels)  # Output: 4
4
4
4
In this code, we access the `wheels` class attribute using both the class name `Car.wheels` and instances `car1.wheels` and `car2.wheels`. The value of the class attribute is the same for all instances.

**Instance Attributes:**

Instance attributes are attributes that are specific to each instance of a class. They are defined within the `__init__` method or any other method of the class. Each instance of the class has its own copy of instance attributes.

Let's modify the `Car` class to include instance attributes for `make` and `model`:

class Car:
    wheels = 4

    def __init__(self, make, model):
        self.make = make
        self.model = model
In this code, the `make` and `model` attributes are instance attributes. They are defined within the `__init__` method and are specific to each instance of the `Car` class.

To access the instance attributes, we can use the dot notation on each instance:

car1 = Car("Toyota", "Camry")
print(car1.make)  # Output: Toyota
print(car1.model)  # Output: Camry

car2 = Car("Honda", "Accord")
print(car2.make)  # Output: Honda
print(car2.model)  # Output: Accord
Toyota
Camry
Honda
Accord
In this code, we access the `make` and `model` instance attributes using the dot notation on each instance. Each instance has its own values for these attributes.

Class attributes and instance attributes serve different purposes. Class attributes are shared among all instances and provide default values or shared information. Instance attributes are specific to each instance and hold unique data for each object.