Python is an object oriented programming language.
Almost everything in Python is an object.
A Class is like a "blueprint" for creating objects or can be called as object factory.
Classes provide a means of bundling data and functionality together.
Classes are defined using keyword class.
The simplest class definition is
class ClassName: "class doc string " statements
# Worlds smallest class class P: # define class name P pass # pass is ust a plcae holder to create an empty class class MyClass: y = 20 class MyClass: x = 10 # data def fun1(self): # function print('Hello class')
When we defined a class with a keyword class, a new namespace is created in the local scope(like for functions using def)
The class name is used to create a class object or instance of the class known as instantiation
Let us create a class Foo
class Foo: pass
We can call the class name Foo (which is a callable name object) like function call to create an instance or object of the class as follows
p = Foo()
"p" is a instance or object of Foo class and it has its reference
A class is a combination of data and methods (logics) which are called as attributes
The attributes (data and methods) inside the class are class members.
When you define anything inside a class it becomes its attribute
class Foo: x = 10 def func(self): # More on methods in next section pass
Here "x" and "func()" are the attributes of class Foo
To access class attribute we use the following syntax
For example in the previous code, let us try to fetch the "x" attribute
class Foo: x = 10 p = Foo() print (p.x) # prints 10 - fetches attribute x - instance.attribute
We can also define functions inside a class. These functions defined inside classes are called as methods.
The first argument (methods must always take at least one argument) is always the instance of the class.
class Foo: # Define class object def func(self): # Define class's method print("Hello world") p = Foo() p.func() # calling the class method, prints "Hello world"
You can see that for func we have a function parameter self in function definition
This is because when we call a method using instance or object , the first the first argument automatically receives that particular object/instance
While calling method
p.func(), the instance "p" is assigned to "self" automatically by python itself
p.func() is same as
Foo.funct(p) as follows
p = Foo() Foo.funct(p) # prints "Hello world"
Besides the first argument, other arguments will act like general function argument
class Foo: def func(self, name, age): print(name, age) p = Foo() p.func("John", 20) # prints - "John" 20 p.func("Doe", 30) # prints - "Doe" 30
Here "p" is assigned to "self" which is first argument.
The other arguments we are passing while calling func , acts like positional arguments and assigned to name and agerespectively
You can use any name instead of self . However, it is a norm to use self.
class Foo: def func(no_self): # no_self instead of self print("Hello world") p = Foo() p.func() # prints "Hello world"
The attributes can be created/initialized/defined inside and outside of a class
Let us see this example
class Employee: def set_data(self, value): self.data = value # Create a attribute sata and attach it self/instance def display_data(self): print(self.data) p = Employee() p.set_data(200) # Setting value to data for instance p p.display_data() p.data = 300 # Re-setting value to data for instance p p.display_data() # Value of data is changed p.new_data = 400 # Can get/set attributes outside calls too print(p.new_data) # prints 400, Can get/set attributes outside calls too
Let us create multiple instances for a particular class.
We can do it by calling class name multiple times
class Foo: def func(no_self): print("Hello world") p = Foo() e = Foo() p.func() e.func()
Let us see how the multiple instances works
There are tow kinds of attributes in python's OOPs model i.e. class attributes and instance attributes
The top level assignments inside a class creates class attributes.
The class attributes are shared by all the instances and any change to the class attribute will change the value across in all the instances
But the instance attributes are attached to the instances and created by setting a attribute to the instance
# Class attributes class Foo: X = 10 # This is a class attribute print(Foo.X) # prints 10 , Class attributes can be accessed using class name p = Foo() e = Foo() # Class attributes shared by all instances print(p.X) # prints 10 , Class attribute accessed by instance print(e.X) # prints 10 , Class attribute accessed by instance # Any change to class attribute will change its value across all instances Foo.X = 20 print(p.X) # prints 20 , Value changed print(e.X) # prints 20 , Value changed
When you assign a name/attribute to instance it becomes instance attribute
p.Y = 30 print(p.Y) # prints 30 print(e.Y) # AttributeError: 'Foo' object has no attribute 'Y'
Assigning a instance attribute using self inside a method
class Foo: def set_value(self, value): self.data = value # Setting a attribute to instance using self p = Foo() e = Foo() p = set_value(10) e = set_value(20) print(p.data) # prints 10 print(e.data) # prints 20
The self in the class method set_value , is nothing but the copy of the instance.
Setting an attribute to instance/object by assigning a value (
self.data = value ), creates an instance attribute and attached it to the self means the particular object/instance.
Therefore , the instance.data prints corresponding data attribute value
A constructor in python is a special type of method called to prepare an object or initialize the variables for an object .
The class methods that starts with double underscore (__) are special for python
One of the special method __init__() is the constructor in python.
The __init__ method is invoked every time a object is created (instantiation).
class Employee: def __init__(self, name, age): self.name = name # Initializing attribute name for instance self.age = age # Initializing attribute age for instance p = Employee("John", 20) # Creating instance "p", invokes __init__() and sets values for name and age for "p" e = Employee("Doe", 30) # Creating instance "e", invokes __init__() and sets values for name and age for "e" print(p.name, p.age) # prints "John", 20 print(e.name, e.age) # prints "Doe", 30
Once you define the __init__ method in a class, then while creating an object (when you call Employee()), you can provide all the necessary parameters required for the object's variables/attribute, because when we call Employee(), the python calls the __init__ method for the created object automatically.
The __init__ method is similar as other class methods and also takes self (instance) as first argument
Its not mandatory to defined __init__ method inside the class.