Skip to main content

Class Variables, Attributes, and Properties

Class variables, attributes, and properties

Python is a powerful language that supports different types of variables and properties. In this article, we will discuss variables, attributes, and properties in Python to help you understand them better.

Understanding Variables, Attributes, and Properties

  • Variables: A variable is a name that refers to a value. Variables can hold any type of object.
  • Attributes: An attribute is a value associated with an object. Attributes can be accessed using the dot notation.
  • Properties: A property is a way to define a method as an attribute. Properties are created using the @property decorator.

Class Attributes

Class attributes are attributes that are shared by all instances of a class. They are defined at the class level, and can be accessed using the class name or any instance of the class.

class MyClass:
    class_attr = 10

obj = MyClass()
print(obj.class_attr)  # 10

Class Property

Python class properties are methods that act like attributes. They are created using the @property decorator.

class MyClass:
    def __init__(self, value):
        self._value = value

    @property
    def value(self):
        return self._value

obj = MyClass(10)
print(obj.value)  # 10

Class Private Variables

Python class private variables are variables that are only accessible within the class. They are defined using the double underscore prefix.

class MyClass:
    __private_var = 10

    def get_private_var(self):
        return self.__private_var

obj = MyClass()
print(obj.get_private_var())  # 10

Class Global Variables

Python class global variables are variables that are accessible from any part of the program. They are defined outside of any function or class.

global_var = 10

class MyClass:
    def __init__(self):
        self.instance_var = global_var

obj = MyClass()
print(obj.instance_var)  # 10

Check if Class has Attribute

Python has a built-in function, hasattr(), that can be used to check if a class has a specific attribute.

class MyClass:
    var = 10

obj = MyClass()

if hasattr(obj, 'var'):
    print('Object has var attribute')
else:
    print('Object does not have var attribute')

How to Print Class Attributes in Python

Python does not have a built-in method for printing all attributes of a class. However, you can use a for loop to iterate through all attributes of a class and print their names and values.

class MyClass:
    var1 = 10
    var2 = 'hello'
    var3 = True

for attr in dir(MyClass):
    if not attr.startswith('__'):
        value = getattr(MyClass, attr)
        print(f'{attr}: {value}')

How to Get Class Attributes

Python has a built-in method, dir(), that can be used to get a list of all attributes of a class.

class MyClass:
    var1 = 10
    var2 = 'hello'
    var3 = True

print(dir(MyClass))

Class Variables vs Instance Variables

Variables, attributes, and properties are essential elements of any programming language. Classes are used to define objects, and each object has its own set of attributes. Two types of variables can be defined in a class: class variables and instance variables.

Python Class Variables

Class variables are shared among all instances of a class. These variables are declared outside of any method of a class and are accessed using the class name.

class MyClass:
    y = 10   # Python class variable
    def __init__(self, x):
        self.x = x  # instance variable

obj1 = MyClass(5)
print(obj1.x)   # prints 5
print(obj1.y)   # prints 10 (accessed using class name)
obj1.y = 20
print(obj1.y)   # prints 20 (now obj1 has its own y)

In the example, y is a class variable, while x is an instance variable. y is accessed using the class name MyClass.y.

Instance Variables

Python instance variables, on the other hand, are unique to each instance of a class. They are defined inside the __init__ method of a class using the keyword self.

class MyClass:
    def __init__(self, x):
        self.x = x  # instance variable
        self.y = 10 # instance variable

obj1 = MyClass(5)
print(obj1.x)   # prints 5
print(obj1.y)   # prints 10

In the example, both x and y are instance variables, as they are unique to each instance of MyClass.

Class Attributes and Properties in Python

Class attributes and properties work similarly to variables, but they are more powerful. Class attributes are defined outside of any method using the class name as with class variables. On the other hand, properties are defined using the @property decorator before a method.

class MyClass:
    x = 0    # Python class attribute
    @property
    def y(self):
        return self._y

    @y.setter
    def y(self, value):
        self._y = value

obj1 = MyClass()
obj1.x = 5
print(obj1.x)   # prints 5 (accessed using the instance)
obj1.y = 10
print(obj1.y)   # prints 10 (accessed using the instance)

In the example, x is a class attribute that can be accessed using the instance. y is a property that has a setter and a getter method. y is accessed using the instance as well.

Private Variables

Python private variables are instance variables that are denoted with a double underscore __ before the variable name. Private variables can only be accessed inside a class.

class MyClass:
    def __init__(self, public_value, private_value):
        self.public_value = public_value
        self.__private_value = private_value

obj1 = MyClass(5, 10)
print(obj1.public_value)    # prints 5 (accessed using the instance)
# print(obj1.__private_value) # AttributeError (cannot be accessed outside the class)

In the example, public_value is a normal instance variable, while __private_value is a private instance variable. It can only be accessed inside the class.

Global Variables

Global variables can be accessed from anywhere in the code. Global variables are defined outside any function or class using the global keyword.

x = 0   # global variable
class MyClass:
    def __init__(self, value):
        global x
        x += value
        self.value = value

obj1 = MyClass(5)
print(x)    # prints 5
obj2 = MyClass(3)
print(x)    # prints 8

In the example, x is a global variable that can be accessed inside the class. All instances of MyClass increment the value of x.

The Role of Private Variables in Classes

Variables in classes are attributes or properties that hold data and values. In a class, variables can be global, instance, or static. Instance variables are unique to each object created from a class, while static variables are shared among all objects of the same class. Global variables are accessible throughout the entire program.

One important concept to note is the role of private variables in classes. Private variables are variables that are meant to be used only within the class and should not be accessed or modified from outside the class. Private variables are denoted by adding two underscores __ before the variable name.

class Car:
    # global variable
    wheels = 4

    def __init__(self, make, model, year):
        # instance variables
        self.__make = make
        self.__model = model
        self.__year = year
        # private variable
        self.__mileage = 0

    def get_make(self):
        return self.__make

    def get_model(self):
        return self.__model

    def get_year(self):
        return self.__year

    # property example
    @property
    def mileage(self):
        return self.__mileage

    # property setter example
    @mileage.setter
    def mileage(self, value):
        self.__mileage = value


# creating an object from Car class
my_car = Car("Tesla", "Model 3", 2022)

# accessing attributes from outside the class
print(my_car.wheels)  # output: 4
print(my_car.get_make())  # output: Tesla

# accessing private variable from outside the class
# gives an AttributeError as it's private
# print(my_car.__mileage)  # AttributeError: 'Car' object has no attribute '__mileage'

# accessing private variable using property method to get value
print(my_car.mileage)  # output: 0

# accessing private variable using property method to set value
my_car.mileage = 1000
print(my_car.mileage)  # output: 1000

In the above example, we have defined a class Car with global, instance, and private variables. We have also used the @property and @property.setter decorators to define a property method that can get and set the value of the private variable __mileage.

class Person:
    # class variable
    planet = "Earth"
    
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
# creating an object from Person class
my_person = Person("John", 30)

# checking if class has attribute
if hasattr(my_person, "name"):
    print("Name exists in Person class")

# printing all attributes of class
print(vars(my_person)) # output: {'name': 'John', 'age': 30}

# getting the value of class variable
print(Person.planet) # output: Earth

In this example, we have defined a class Person with a class variable planet and instance variables name and age. We use the hasattr() function to check if an attribute exists in the class and the vars() function to list all attributes of the class. We also use the syntax Class.variable_name to access the value of the class variable planet.

Accessing Class Variables in Python

In Python, class variables are variables that are shared among all instances of a class. These variables are defined within the class but outside any method, and they retain their value across different instances of the class.

Example 1: Accessing Class Variables through the Class

class Student:
    # Class variable
    class_name = "Python Programming"

    def __init__(self, name):
        self.name = name

# Accessing the class variable using the class name
print(Student.class_name)  # Output: Python Programming

In the above example, the class_name variable is a class variable that stores the name of the class. It is accessed using the class name (Student.class_name).

Example 2: Accessing Class Variables through Instances

class Circle:
    # Class variable
    PI = 3.14159

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

    def calculate_area(self):
        # Accessing the class variable through an instance
        area = self.radius * self.radius * Circle.PI
        return area

# Creating an instance of the Circle class
circle = Circle(5)

# Calling the instance method to calculate the area
area = circle.calculate_area()

print("Area:", area)  # Output: Area: 78.53975

In this example, the PI variable is a class variable that stores the value of pi. It is accessed through the Circle instance (self.radius * self.radius * Circle.PI) within the calculate_area method.

Class variables can be accessed through the class name or through instances of the class. When accessed through instances, the variable can be referred to as self.variable_name or instance_name.variable_name.

Difference between Class Attributes and Properties in Python

In Python, class attributes and properties are both mechanisms to store and access data within a class. However, they have some key differences in terms of their implementation and behavior.

Class Attributes

Class attributes are variables that are defined within a class but outside any methods. They are shared among all instances of the class and can be accessed using the class name or through instances of the class. Class attributes are typically used to store data that is common to all instances of the class.

class Circle:
    # Class attribute
    PI = 3.14159

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

    def calculate_area(self):
        # Accessing the class attribute
        area = Circle.PI * self.radius * self.radius
        return area

# Creating an instance of the Circle class
circle = Circle(5)

# Calling the instance method to calculate the area
area = circle.calculate_area()

print("Area:", area)  # Output: Area: 78.53975

In this example, PI is a class attribute that stores the value of pi. It is accessed using the class name Circle.PI within the calculate_area method.

Properties

Properties, on the other hand, provide a way to define getter, setter, and deleter methods for accessing and modifying class attributes. They allow for more control and customization of attribute access. Properties are defined using the @property decorator for the getter method, and the @attribute_name.setter and @attribute_name.deleter decorators for the setter and deleter methods, respectively.

class Rectangle:
    def __init__(self, width, height):
        self._width = width
        self._height = height

    @property
    def width(self):
        return self._width

    @width.setter
    def width(self, value):
        if value > 0:
            self._width = value

    @property
    def height(self):
        return self._height

    @height.setter
    def height(self, value):
        if value > 0:
            self._height = value

    def calculate_area(self):
        area = self._width * self._height
        return area

# Creating an instance of the Rectangle class
rectangle = Rectangle(5, 7)

# Accessing and modifying attributes using properties
print("Width:", rectangle.width)  # Output: Width: 5
rectangle.width = 10
print("Modified Width:", rectangle.width)  # Output: Modified Width: 10

# Calling the instance method to calculate the area
area = rectangle.calculate_area()

print("Area:", area)  # Output: Area: 70

In this example, properties width and height are defined to provide controlled access to the corresponding attributes _width and _height. The getter methods retrieve the values, and the setter methods allow for validation and modification before assigning new values.

In summary, class attributes are used to store shared data among instances, while properties provide a way to customize attribute access and modification using getter, setter, and deleter methods.

Public, Protected, and Private Attributes and Properties in Python

In Python, attributes and properties can have different levels of visibility: public, protected, and private. These visibility levels indicate the intended accessibility and usage of the attributes and properties within a class.

Public Attributes and Properties

Public attributes and properties have no special prefix and are accessible from anywhere, both within and outside the class. They can be freely accessed, modified, and assigned values.

Protected Attributes and Properties

Protected attributes and properties are indicated by a single underscore prefix _. Although they can still be accessed and modified, it is considered a best practice to treat them as internal implementation details.

class Person:
    def __init__(self, _name):
        self._name = _name

    def display(self):
        print("Name:", self._name)

# Creating an instance of the Person class
person = Person("John Doe")

# Accessing and modifying protected attributes (not recommended)
print(person._name)  # Output: John Doe
person._name = "Jane Smith"

# Displaying the person's information
person.display()

In this example, the _name attribute is marked as protected. Although it can still be accessed directly from outside the class, it is recommended to treat it as an internal detail and rely on class methods or properties for access and manipulation.

Private Attributes and Properties

Private attributes and properties are indicated by a double underscore prefix __. They are strongly discouraged from being accessed or modified from outside the class. Attempting to access or modify a private attribute or property directly from outside the class will result in a name mangling mechanism, which changes the attribute's name.

class BankAccount:
    def __init__(self, __account_number):
        self.__account_number = __account_number

    def display(self):
        print("Account Number:", self.__account_number)

# Creating an instance of the BankAccount class
account = BankAccount("123456789")

# Accessing and modifying private attributes (not recommended)
print(account._BankAccount__account_number)  # Output: 123456789
account._BankAccount__account_number = "987654321"

# Displaying the account information
account.display() # Output: Account Number: 987654321

In this example, the __account_number attribute is marked as private. Accessing it directly from outside the class is discouraged, but it can still be accessed using the name mangling mechanism.

It's important to note that the use of protected and private attributes and properties in Python is based on conventions rather than strict access control mechanisms.

Updated: 07/01/2023 - 19:59
Profile picture for user AliaksandrSumich
Python engineer, expert in third-party web services integration.