Class and instance attributes

What is a class?

Flavio Orlando
3 min readJan 11, 2021

--

A class is a code template for creating objects along with related data and functions. Objects have variables and behavior associated with them. In Python a class is created by the keyword class.

An object is created using the constructor of the class. This object will then be called the instance of the class. In Python we create instances in the following manner

Instance = class(arguments)

Attributes and Methods in class:

A class by itself has no purpose unless there is some functionality associated to it. These functionalities are defined by setting attributes, which act as containers for data and functions related to those attributes. Functions within classes are called methods.

Instance Attribute

An instance attribute is a Python variable that belongs to one specific object. It is only accessible when working from within the object itself and it is defined inside the constructor function of a class.

For example, __init__(self,..).

Class Attribute

A class attribute is a Python variable that belongs to a class instead than to an specific object. Class attributes are shared between all objects within the same class and are defined outside the constructor function __init__(self,…), of the class.

Differences Between Class and Instance Attributes

As mentioned before, class attributes are common to all instances within the class, thus, changing the value of a class attribute will affect every instance of the class that have that attribute. The attribute of an instance on the other hand is unique to that instance.

What are the advantages and drawbacks of each of them

While class attributes are more flexible to declare and call, the downside is that they are available to the entire class. That means that after being called and given different values, it’s final value when called as a return value may be unexpected, as their may be side effects that you were not counting on.

With instance attributes, since they are only available in the scope of the object that created it, it is encapsulated (protected) but the use of the instance attribute is far less flexible than the class attribute.

__dict__

A __dict__ is a dictionary containing the module’s symbol table, or in other words, used to store an object’s attributes. It is created by the execution engine along with the class it belongs to.

How does Python deal with the object and class attributes using the __dict__ ? Basically it contains all the attributes which describe the object in question and it can be used to alter or read the attributes.

The __dict__ documentation says the following:

A dictionary or other mapping object used to store an object’s (writable) attributes.

In fact, if you print out__dict__ for the following example:

#!/usr/bin/python3
class Person:
"""Defines Person class"""
#Class Variable
class_variable = "Class variable content"
def __init__(self, name, last_name):
"""Constructor method __init__"""
# Instance properties
self.name = name
self.last_name = last_name
#str method definition
def __str__(self):
"""Defines string to return"""
str = self.name + self.last_name
return(str)
#instance creation
person1 = Person ("Kurt", "Cobain")
#dir print
print("Person __dict__:", Person.__dict__)
print("")
print("person1 __dict__:", person1.__dict__)

You will be able to actually see how the variables are stored in the dictionary for both class and instance

Person __dict__: {'__module__': '__main__', '__doc__': 'Defines Person class', 'class_variable': 'Class variable content', '__init__': <function Person.__init__ at 0x0000028833B58820>, '__str__': <function Person.__str__ at 0x0000028833B588B0>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>}person1 __dict__: {'name': 'Kurt', 'last_name': 'Cobain'}

Creating Classes and Instance Pythonic and non-Pythonic

A non-Pythonic way would be like this:

class Square:
def __init__(self, size=0):
if not isinstance(size, int):
raise TypeError("size must be an integer")

if size < 0:
raise ValueError("size must be >= 0")

self.__size = size * size def area(self):
return self.__sizet__width()

The disadvantage comes when we need to modify the code. The pythonic way of doing it would be to use getter and setter property methods.

class Square:
def __init__(self, size=0):
self.size = size @property
def size(self):
return self.__size @size.setter
def size(self, value):
if not isinstance(value, int):
raise TypeError("size must be an integer")
if value < 0:
raise ValueError("size must be >= 0")
self.__size = value def area(self):
return self.__size * self.__size

The advantage of using property allows us to attach code to the self.size attribute and any code assigned the value of size will be called with size in def size.

--

--