Download as pdf or txt
Download as pdf or txt
You are on page 1of 22

What is namespace:

A namespace is a system that has a unique name for each and every object in Python. An object might
be a variable or a method. Python itself maintains a namespace in the form of a Python dictionary. Let’s
go through an example, a directory-file system structure in computers. Needless to say, that one can
have multiple directories having a file with the same name inside every directory. But one can get
directed to the file, one wishes, just by specifying the absolute path to the file.
Types of namespaces :

When Python interpreter runs solely without any user-defined modules, methods, classes, etc. Some
functions like print(), id() are always present, these are built-in namespaces. When a user creates a
module, a global namespace gets created, later the creation of local functions creates the local
namespace. The built-in namespace encompasses the global namespace and the global namespace
encompasses the local namespace.

The lifetime of a namespace :

A lifetime of a namespace depends upon the scope of objects, if the scope of an object ends, the
lifetime of that namespace comes to an end. Hence, it is not possible to access the inner namespace’s
objects from an outer namespace.

count = 5
def some_method():
global count
count = count + 1
print(count)
some_method()
Output:
6

dir(__builtins__)
Python Classes and Objects
A class is a user-defined blueprint or prototype from which objects are created. Classes provide a
means of bundling data and functionality together. Creating a new class creates a new type of
object, allowing new instances of that type to be made.

Each class instance can have attributes attached to it for maintaining its state. Class instances can
also have methods (defined by their class) for modifying their state.

Classes are created by keyword class.

Attributes are the variables that belong to a class.

Attributes are always public and can be accessed using the dot (.) operator. Eg.:
Myclass.Myattribute
Class Definition Syntax:

class ClassName(object)[optional]:
# Statement-1
.
.
.
# Statement-N

Create a class named MyClass, with a property named x:

class MyClass:
x = 5

Object
An Object is an instance of a Class. A class is like a blueprint while an instance is a copy of the
class with actual values.

An object consists of :

State: It is represented by the attributes of an object. It also reflects the properties of an object.

Behavior: It is represented by the methods of an object. It also reflects the response of an object
to other objects.

Identity: It gives a unique name to an object and enables one object to interact with other objects.

Create an object named p1, and print the value of x:

p1 = MyClass()
print(p1.x)

Declaring Objects (Also called instantiating a class)

When an object of a class is created, the class is said to be instantiated. All the instances share
the attributes and the behavior of the class. But the values of those attributes, i.e. the state are
unique for each object. A single class may have any number of instances.
class MyClass:
x = 5

p1 = MyClass()

print(p1.x)

p2 = MyClass()

p2.x=6

print(p2.x)

output:

Constructors

Constructors are generally used for instantiating an object. The task of constructors is to
initialize(assign values) to the data members of the class when an object of the class is created. In
Python the __init__() method is called the constructor and is always called when an object is
created.

Syntax of constructor declaration :

def __init__(self):

# body of the constructor

Types of constructors :

default constructor: The default constructor is a simple constructor which doesn’t accept any
arguments. Its definition has only one argument which is a reference to the instance being
constructed.

class person:

# default constructor
def __init__(self):
self.x = "name:"

# a method for printing data members


def print_person(self):
print(self.x)

# creating object of the class


obj = person()

# calling the instance method using the object obj


obj.print_person()

parameterized constructor: constructor with parameters is known as parameterized constructor.


The parameterized constructor takes its first argument as a reference to the instance being
constructed known as self and the rest of the arguments are provided by the programmer.
class Addition:

x first = 0

ysecond = 0

aznswer = 0

# parameterized constructor

def __init__(self, f, s):

self.first = f

self.second = s

def display(self):

print("First number = " + str(self.first))

print("Second number = " + str(self.second))

print("Addition of two numbers = " + str(self.answer))

def calculate(self):

self.answer = self.first + self.second

# creating object of the class

# this will invoke parameterized constructor

obj = Addition(1000, 2000)

# perform Addition
obj.calculate()

# display result

obj.display()

The __init__() Function

The examples above are classes and objects in their simplest form, and are not really useful in
real life applications.

To understand the meaning of classes we have to understand the built-in __init__() function.

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

Use the __init__() function to assign values to object properties, or other operations that are
necessary to do when the object is being created:

Create a class named Person, use the __init__() function to assign values for name and age:

class Person:

def __init__(self, name, age):

self.name = name

self.age = age

p1 = Person("John", 36)

print(p1.name)

print(p1.age)

The self

Class methods must have an extra first parameter in the method definition. We do not give a
value for this parameter when we call the method, Python provides it.

If we have a method that takes no arguments, then we still have to have one argument.

This is similar to this pointer in C++ and this reference in Java.

When we call a method of this object as myobject.method(arg1, arg2), this is automatically


converted by Python into MyClass.method(myobject, arg1, arg2) – this is all the special self is
about.
The self parameter is a reference to the current instance of the class, and is used to access
variables that belongs to the class.

It does not have to be named self , you can call it whatever you like, but it has to be the first
parameter of any function in the class:

Example

Use the words mysillyobject and abc instead of self:

class Person:

def __init__(mysillyobject, name, age):

mysillyobject.name = name

mysillyobject.age = age

def myfunc(abc):

print("Hello my name is " + abc.name)

p1 = Person("John", 36)

p1.myfunc()

Modify Object Properties


You can modify properties on objects like this:

Object.variable_name=value

Example

Set the age of p1 to 40:

p1.age = 40

Object Methods

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

Let us create a method in the Person class:

Insert a function that prints a greeting, and execute it on the p1 object:


class Person:

def __init__(self, name, age):

self.name = name

self.age = age

def myfunc(self):

print("Hello my name is " + self.name)

p1 = Person("John", 36)

p1.myfunc()

example:
class fun(object):

# default constructor

def __init__(self):

self.fun = "pscmr"

# a method for printing data members

def print_fun(self):

print(self.fun)

# creating object of the class

obj = fun()

# calling the instance method using the object obj

obj.print_fun()

Inheritance

Inheritance is the capability of one class to derive or inherit the properties from another class.
The benefits of inheritance are:

It represents real-world relationships well.


It provides reusability of a code. We don’t have to write the same code again and again. Also, it
allows us to add more features to a class without modifying it.

It is transitive in nature, which means that if class B inherits from another class A, then all the
subclasses of B would automatically inherit from class A.

class Person(object):

# Constructor

def __init__(self, name):

self.name = name

# To get name

def getName(self):

return self.name

# To check if this person is an employee

def isEmployee(self):

return False

# Inherited or Subclass (Note Person in bracket)

class Employee(Person):

# Here we return true

def isEmployee(self):

return True

# Driver code

emp = Person("pscmr") # An Object of Person

print(emp.getName(), emp.isEmployee())

emp = Employee("pscmrece") # An Object of Employee

print(emp.getName(), emp.isEmployee())

pscmr false

pscmrece true

A Python program to demonstrate


# inheritance

# Base class or Parent class


class Child:

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

# To get name
def getName(self):
return self.name

# To check if this person is student


def isStudent(self):
return False

# Derived class or Child class


class Student(Child):

# True is returned
def isStudent(self):
return True

# Driver code
# An Object of Child
std = Child("Ram")
print(std.getName(), std.isStudent())

# An Object of Student
std = Student("Shivam")
print(std.getName(), std.isStudent())

# Python program to demonstrate


# multiple inheritance

# Base class1

class Mother:

mothername = ""

def mother(self):

print(self.mothername)

# Base class2

class Father:

fathername = ""

def father(self):

print(self.fathername)

# Derived class

class Son(Mother, Father):

def parents(self):

print("Father :", self.fathername)

print("Mother :", self.mothername)

# Driver's code

s1 = Son()

s1.fathername = "RAM"

s1.mothername = "SITA"

s1.parents()
# Python program to demonstrate
# multilevel inheritance

# Base class
class Grandfather:

def __init__(self, grandfathername):


self.grandfathername = grandfathername

# Intermediate class
class Father(Grandfather):
def __init__(self, fathername, grandfathername):
self.fathername = fathername

# invoking constructor of Grandfather class


Grandfather.__init__(self, grandfathername)

# Derived class
class Son(Father):
def __init__(self,sonname, fathername, grandfathername):
self.sonname = sonname

# invoking constructor of Father class


Father.__init__(self, fathername, grandfathername)

def print_name(self):
print('Grandfather name :', self.grandfathername)
print("Father name :", self.fathername)
print("Son name :", self.sonname)

# Driver code
s1 = Son('Prince', 'Rampal', 'Lal mani')
print(s1.grandfathername)
s1.print_name()
Hierarchical Inheritance: When more than one derived classes are created from a single base this
type of inheritance is called hierarchical inheritance. In this program, we have a parent (base) class and
two child (derived) classes.

Python program to demonstrate


# Hierarchical inheritance

# Base class
class Parent:
def func1(self):
print("This function is in parent class.")

# Derived class1
class Child1(Parent):
def func2(self):
print("This function is in child 1.")

# Derivied class2
class Child2(Parent):
def func3(self):
print("This function is in child 2.")

# Driver's code
object1 = Child1()
object2 = Child2()
object1.func1()
object1.func2()
object2.func1()
object2.func3()
Hybrid Inheritance: Inheritance consisting of multiple types of inheritance is called hybrid inheritance.

# Python program to demonstrate

# hybrid inheritance

class School:
def func1(self):

print("This function is in school.")

class Student1(School):

def func2(self):

print("This function is in student 1. ")

class Student2(School):

def func3(self):

print("This function is in student 2.")

class Student3(Student1, School):

def func4(self):

print("This function is in student 3.")

# Driver's code

object = Student3()

object.func1()

object.func2()

Creating Nested Functions in Python


Let’s start with a code example containing a nested function:

def outer_func():
def inner_func():
print("Hello, World!")
inner_func()
outer_func()
def factorial(number):
if not isinstance(number, int):
raise TypeError("The number must be whole.")
if number < 0:
raise ValueError("The number must be non-negative.")
#Factorial calculation
def inner_factorial(number):
if number <= 1:
return 1
return number * inner_factorial(number - 1)
return inner_factorial(number)
factorial(4)

What is Polymorphism: The word polymorphism means having many forms. In programming,
polymorphism means the same function name (but different signatures) being used for different types.

# Python program to demonstrate in-built poly-


# morphic functions

# len() being used for a string


print(len("pscmr"))

# len() being used for a list


print(len([10, 20, 30]))

ex-2:
# A simple Python function to demonstrate
# Polymorphism

def add(x, y, z = 0):


return x + y+z

# Driver code
print(add(2, 3))
print(add(2, 3, 4))
Output:
5
9
Polymorphism with class methods:
The below code shows how Python can use two different class types, in the same way. We create a for
loop that iterates through a tuple of objects. Then call the methods without being concerned about
which class type each object is. We assume that these methods actually exist in each class.
class India():
def capital(self):
print("New Delhi is the capital of India.")

def language(self):
print("Hindi is the most widely spoken language of India.")

def type(self):
print("India is a developing country.")

class USA():
def capital(self):
print("Washington, D.C. is the capital of USA.")

def language(self):
print("English is the primary language of USA.")

def type(self):
print("USA is a developed country.")

obj_ind = India()
obj_usa = USA()
for country in (obj_ind, obj_usa):
country.capital()
country.language()
country.type()
Output:
New Delhi is the capital of India.
Hindi is the most widely spoken language of India.
India is a developing country.
Washington, D.C. is the capital of USA.
English is the primary language of USA.
USA is a developed country.
Polymorphism with Inheritance:
In Python, Polymorphism lets us define methods in the child class that have the same name as the
methods in the parent class. In inheritance, the child class inherits the methods from the parent class.
However, it is possible to modify a method in a child class that it has inherited from the parent class.
This is particularly useful in cases where the method inherited from the parent class doesn’t quite fit the
child class. In such cases, we re-implement the method in the child class. This process of re-
implementing a method in the child class is known as Method Overriding.
class Bird:

def intro(self):
print("There are many types of birds.")

def flight(self):
print("Most of the birds can fly but some cannot.")
class sparrow(Bird):
def flight(self):
print("Sparrows can fly.")

class ostrich(Bird):
def flight(self):
print("Ostriches cannot fly.")

obj_bird = Bird()
obj_spr = sparrow()
obj_ost = ostrich()

obj_bird.intro()
obj_bird.flight()

obj_spr.intro()
obj_spr.flight()

obj_ost.intro()
obj_ost.flight()
Output:
There are many types of birds.
Most of the birds can fly but some cannot.
There are many types of birds.
Sparrows can fly.
There are many types of birds.
Ostriches cannot fly.

Polymorphism with a Function and objects:


It is also possible to create a function that can take any object, allowing for polymorphism. In this
example, let’s create a function called “func()” which will take an object which we will name “obj”.
Though we are using the name ‘obj’, any instantiated object will be able to be called into this function.
Next, let’s give the function something to do that uses the ‘obj’ object we passed to it. In this case, let’s
call the three methods, viz., capital(), language() and type(), each of which is defined in the two classes
‘India’ and ‘USA’. Next, let’s create instantiations of both the ‘India’ and ‘USA’ classes if we don’t have
them already. With those, we can call their action using the same func() function:
def func(obj):

obj.capital()
obj.language()
obj.type()

obj_ind = India()
obj_usa = USA()

func(obj_ind)
func(obj_usa)
Implementing Polymorphism with a Function

class India():

def capital(self):

print("New Delhi is the capital of India.")

def language(self):

print("Hindi is the most widely spoken language of India.")

def type(self):

print("India is a developing country.")

class USA():

def capital(self):

print("Washington, D.C. is the capital of USA.")

def language(self):

print("English is the primary language of USA.")

def type(self):

print("USA is a developed country.")

def func(obj):

obj.capital()

obj.language()

obj.type()

obj_ind = India()

obj_usa = USA()

func(obj_ind)
func(obj_usa)

Output:
New Delhi is the capital of India.
Hindi is the most widely spoken language of India.
India is a developing country.
Washington, D.C. is the capital of USA.
English is the primary language of USA.
USA is a developed country.

Method overriding is an ability of any object-oriented programming language that allows a subclass or
child class to provide a specific implementation of a method that is already provided by one of its
super-classes or parent classes. When a method in a subclass has the same name, same parameters
or signature and same return type(or sub-type) as a method in its super-class, then the method in the
subclass is said to override the method in the super-class.

The version of a method that is executed will be determined by the object that is used to invoke it. If an
object of a parent class is used to invoke the method, then the version in the parent class will be
executed, but if an object of the subclass is used to invoke the method, then the version in the child
class will be executed. In other words, it is the type of the object being referred to (not the type of the
reference variable) that determines which version of an overridden method will be executed.

# Python program to demonstrate

# method overriding

# Defining parent class

class Parent():

# Constructor

def __init__(self):

self.value = "Inside Parent"

# Parent's show method

def show(self):

print(self.value)
# Defining child class

class Child(Parent):

# Constructor

def __init__(self):

self.value = "Inside Child"

# Child's show method

def show(self):

print(self.value)

# Driver's code

obj1 = Parent()

obj2 = Child()

obj1.show()

obj2.show()

Output:
Inside Parent
Inside Child
Method overriding with multiple and multilevel inheritance

Multiple Inheritance: When a class is derived from more than one base class it is called multiple
Inheritance.

Example: Let’s consider an example where we want to override a method of one parent class only.
Below is the implementation.

# Python program to demonstrate

# overriding in multiple inheritance

# Defining parent class 1


class Parent1():

# Parent's show method

def show(self):

print("Inside Parent1")

# Defining Parent class 2

class Parent2():

# Parent's show method

def display(self):

print("Inside Parent2")

# Defining child class

class Child(Parent1, Parent2):

# Child's show method

def show(self):

print("Inside Child")

# Driver's code

obj = Child()

obj.show()

obj.display()

Inside Child
Inside Parent2
Calling the Parent’s method within the overridden method
Parent class methods can also be called within the overridden methods. This can generally be
achieved by two ways.
 Using Classname: Parent’s class methods can be called by using the
Parent classname.method inside the overridden method.
Example:
# Python program to demonstrate

# calling the parent's class method

# inside the overridden method

class Parent():

def show(self):

print("Inside Parent")

class Child(Parent):

def show(self):

# Calling the parent's class

# method

Parent.show(self)

print("Inside Child")

# Driver's code

obj = Child()

obj.show()

 Output:
 Inside Parent
 Inside Child

 Using Super(): Python super() function provides us the facility to refer to the parent class
explicitly. It is basically useful where we have to call superclass functions. It returns the proxy object
that allows us to refer parent class by ‘super’.
# Python program to demonstrate

# calling the parent's class method

# inside the overridden method using

# super()

class Parent():

def show(self):

print("Inside Parent")

class Child(Parent):

def show(self):

# Calling the parent's class

# method

super().show()

print("Inside Child")

# Driver's code

obj = Child()

obj.show()

You might also like