Whereas a class attribute is a value that exists for each instance of that class, we can also create class variables that are accessible to all instances of that class. Class variables are useful when there is need for values which are shared by all instances of the class.

To define them, we simply declare the variable inside the class definition but outside any specific method (and without using the self keyword, since we are associating the value with all instances of the class):

class SavingsAccount:
    general_rate = 0.03
 
    def __init__(self, account_number: str, balance: float, interest_rate: float):
        self.__account_number = account_number
        self.__balance = balance
        self.__interest_rate = interest_rate
 
    def add_interest(self):
        # The total interest rate equals 
        # the general rate + the interest rate of the account
        total_interest = SavingsAccount.general_rate + self.__interest_rate
        self.__balance += self.__balance * total_interest
 
    @property
    def balance(self):
        return self.__balance

With the example above, we can modify the general_rate for all instances of SavingsAccount, even if they have been instantiated already:

account1 = SavingsAccount("12345", 100, 0.03)
account2 = SavingsAccount("54321", 200, 0.06)
 
print("General interest rate:", SavingsAccount.general_rate)
print(account1.total_interest)
print(account2.total_interest)
 
# The general rate of interest is now 10 percent
SavingsAccount.general_rate = 0.10
 
print("General interest rate:", SavingsAccount.general_rate)
print(account1.total_interest)
print(account2.total_interest)