Classes and Objects in Python

Object-oriented programming (OOP) is a programming paradigm that depends on the concept of objects. Objects communicate with one another and that is the means by which the program functions. Objects have states and behaviors. Numerous objects can have similar characteristics and if you think you have to work with them in your program it might be easier to make a class for similar objects. Classes represent the normal structure of similar objects: their data and their behavior.

Declaring Classes

Classes are declared with a keyword class and name of the class:

class Classname:
    var = ...  
 
    def func_name(self):
    # some method

For the most part, class name begins with a capital letter and it is generally a noun or a noun phrase. The names of the classes follow the CapWords show: implying that if it’s a phrase, all words in the phrase are capitalized and composed without underscores between them.

Classes permit you to characterize the data and the behaviors of similar objects. The behavior is depicted by methods. A method is like a function in that it is a block of code that has a name and performs a specific activity. Methods, however, are not independent since they are defined inside a class. Data inside classes are stored in the attributes (variables) and there are two kinds of them: class attributes and instance attributes. The difference between those two will be clarified below.

Common error which occurs while creating a class is :

class Person:
age = 50

    def hello(self):
        print('Hello')
print(Person.age)

Output

We can clearly see that though our code is correct but due to improper indentation it raises an IndentationError.

Class Attribute

A class attribute is an attribute shared by all instances of the class.

Let’s understand from an example:

class Book:
    material = "paper"
    cover = "paperback"
    all_books = []

This class has a string variable material with the value “paper”, a string variable cover with the value “paperback” and an empty list as a characteristic all_books. Each one of those variables are class attributes and they can be accessed using the dot(.) with the name of the class:

Book.material 
Book.cover 
Book.all_books

Class properties are characterized inside the class yet outside of any methods. Their value is the equivalent for all instances of that class so you could consider them as such a “default” values for all objects.

As for instance variables, they store the data unique to each object of the class.

Class instance

Let’s try to create a instance for the Book class.

my_book = Book()

Here we not just made a instance of a Book class yet additionally assigned it to the variable my_book. The syntax of instantiating a class object takes after the function notation: after the class name, we compose brackets.

Our my_book object approaches the contents of the class Book: its attributes and methods.

print(my_book.material)  
print(my_book.cover)  
print(my_book.all_books)

Output

The __init__() Function

All classes have a function called __init__(), which is constantly executed when the class is being initiated.

Utilize the __init__() function to assign values to object properties, or different activities that are important to do when the object is being created:

class Books:
  def __init__(self, material, cover):
    self.material = material
    self.cover = cover

p1 = Books("Paper","paperback")

print(p1.material)
print(p1.cover)

Output

The __init__() function is called automatically every time the class is being used to create a new object.

Objects in Python

Objects can also contain methods. Methods in objects are functions that belong to the object.

Reference to an Object

In Python, all values are stored in objects. You can believe that an object resembles a container that contains data about some value and furthermore stores some extra information, for example, its identity. At the point when you assign a value to a variable, for example string = “hello”, Python makes another object, puts this value (the string “hello” in our case) inside the new object and afterward makes a reference from the variable name string to the object.

Then, if we assign one variable to another, e.g. new_string = string, Python will create a reference from the new variable new_string to the same object.

Let’s use the id function to see that both variables refer to the same object:

string = "Hello"
new_string = string
print(id(string))       
print(id(new_string))

As a result, you can access the object using any of the two variable names. You can also assign a new value to one of these variables and this will not affect the other one.

string = "hello"
new_string = string
string = "world"
 
print(string, id(string))           
print(new_string, id(new_string))

 

Mutable objects and references

Let’s accept a list for instance. The thing is, a list doesn’t store its values inside itself. Rather, it stores references to objects that store values. For instance, when you compose lst = [2, 3, 9], Python makes the accompanying structure:

lst = [2, 3, 9]
new_lst = lst
 
print(lst, id(lst))            
print(new_lst, id(new_lst))   

lst[2] = 0
print(lst, id(lst))        

print(new_lst, id(new_lst))
x = [10, 20, 30]
print(x)
print(id(x))
x.pop()
print(x)
print(id(x))

Output

The self Parameter

The self parameter is a reference to the current instance of the class, and is utilized to get to factors that belongs to the class.

It doesn’t need to be named self , you can consider it whatever you like, yet it must be the first parameter of any function in the class:

class Calculations:
  def __init__(self, add, sub):
    self.add = add
    self.sub = sub
    
  def print(abc):
    print("Addition:", abc.add)
    print("Subtraction:",abc.sub)
p1 = Calculations("20 + 30 = 50","30 - 20 = 10")
p1.print()

Output

The pass Statement

class definitions cannot be empty, but if you for some reason have a class definition with no content, put in the pass statement to avoid getting an error.

class Sum:
    pass

Delete objects

You can also delete objects. The syntax for deleting objects are:

del obj_name

Modify objects

For modifying objects you need to do the following:

p1.sum = 90

Hence, we can conclude:

  • Variables in Python do not store values themselves, they store references to objects that store values.
  • When we assign one variable to another, they refer to the same object.
  • After modifying mutable objects, other variables referring to it will also change.

Let’s put all the concepts together and understand with the help of an example:

class Employee:
   empCount = 0

   def __init__(self, name, salary):
      self.name = name
      self.salary = salary
      Employee.empCount += 1
   
   def displayCount(self):
     print("Total Employee %d" % Employee.empCount)

   def displayEmployee(self):
      print("Name : ", self.name,  ", Salary: ", self.salary)

print("first object of Employee class")
emp1 = Employee("Joseph", 20000)
print("second object of Employee class")
emp2 = Employee("Anne", 57000)
emp1.displayEmployee()
emp2.displayEmployee()
print("Total Employee %d" % Employee.empCount)

Output