w3resource

Python Classes

Introduction

The basic idea behind an object-oriented programming (OOP) is to combine both data and associated procedures (known as methods) into a single unit which operate on the data. Such a unit is called an object.

Python is an object-oriented language, everything in Python is an object.

We have already worked with some objects in Python, (See Python data type chapter) for example strings, lists are objects defined by the string and list classes which are available by default into Python. Let's declare two objects a string and a list and test their type with type() function.

python class type

As string1 is an object, strings "Good Morning" can produce an uppercase or lowercase version of themselves calling upper() and lower() methods associated with the string. Check it in the Python IDLE.

python calling methods

 

Note : To see the list of string methods execute the following command in Python IDLE
>>>help(str)

Before introducing classes we must discuss something about local variables, global statement, and a nonlocal statement as well as Namespaces and scope rules.

Local Variables:

When a variable is declared inside a function, that variable is accessible only from that function or statements block where it is declared. The variable has no relation with any other variable with the same name declared outside the function, therefore the variable is local to the function. See the following example.

# python-local-variable.py
def function_local(a):
	print('a is -> ',a)
	a = 50
	print('After new value within the function a is -> ',a)
a = 100
function_local(40)
print('Value of a is ->',a)

Output:

a is ->  40
After new value within the function a is ->  50
Value of a is -> 100

Explanation:

Line No.- 2 : Declared a function function_local(a) with a parameter
Line No.- 3 : Print 'a' uses the value of the parameter. [The value of a is now 100 as we assign a to 100 (Line No. 6) before executing the function (Line No. 7).]
Line No.- 4 : Assign the value 50 to 'a'.
Line No.- 5 : Again print 'a', as a is local within the function, therefore, the value of a is now 50.
Line No.- 8 : This is the last print statement and 'a' becomes 100. So far what we have done within the function which has no effect on the function. This is called the scope of the variable.

global statement:

The purpose of the global statement is to assign a value to a variable which is declared outside the function. Free variables (See Line No. 06 in the previous example) may refer to global without declaring global. The syntax of global statement is -> global var_name1, var_name2, ..
See the following example:

# python-global-variable.py
def function_local():
        global a
        print('a is -> ',a)
        a = 50
        print('After new value within the function a is -> ',a)
a = 100
function_local()
print('Value of a is ->',a)

Output:

a is -> 100
After new value within the function a is -> 50
 Value of a is -> 50

Explanation:

Line No.- 3 : The variable 'a' is declared as a global variable, therefore the value of a is now 100.
Line No.- 5 : Assign the value 50 to 'a' and it will hold same value inside and outside the function unless we assign a new value.

nonlocal statement

The nonlocal statement is used to rebind variables found outside of the innermost scope. See the following example without a nonlocal statement.

def outside():
       a = 10
       def inside():

           a = 20
           print("Inside a ->", a)
       inside()
       print("outside a->", a)
outside()
python local varaible example

In the above example the first print() statement simply print the value of 'a', which is 20 as 'a' is local within inside() function. The second print() statement prints the value 'a', which is 10 as the inside() function has no effect. Now we introduce a nonlocal statement in inside() function and the code will be:


def outside():
       a = 10
       def inside():
              nonlocal a
              a = 20
              print("The value of a in inside() function - ", a)
       inside()
       print("The value of a in outside() function -  ", a)
outside()
python nonlocal variable

The second print() statement prints the value 'a', which is 20 as the variable 'a' is rebound..

Python Scopes and Namespaces:

In general, a namespace is a naming system to create unique names. In daily experience, we see railway stations, airports, the capital of various states, the directory structure of filesystems have unique names. As of other programming language Python uses namespaces for identifiers.

A namespace is a mapping from names to objects.

  - For example 'a' maps to [1, 2, 3] or 'a' maps to the value 25.

  - Most namespaces currently implemented as Python dictionaries (containing the names and values of the objects).

  - Names in different namespaces have absolutely no relationship (e.g. the variable 'a' can be bound to different objects in different namespaces).

  - Examples of the namespace : The global name of a module, local names in a function invocation, built-in names (containing functions such as min()), attributes of an object.

Python creates namespaces at different times.

  - The built-in namespace is created when Python interpreter starts and is never deleted.

  - The global namespace for a module is created when the module is called and last until the interpreter quits.

  - The local namespace for a function is created when the function is called and deleted when the function returns.

A scope is a textual region of a Python program where a namespace is directly accessible. The scopes in python are as follows:

  - The local scope, searched first, contains the local name.

  - Enclosing scope (in an enclosing function) contains non-local and non-global names.

  - The current module's global names.

  - The outermost scope is the namespace containing built-in names.

Defining a class:

In object oriented programming classes and objects are the main features. A class creates a new data type and objects are instances of a class which follows the definition given inside the class. Here is a simple form of class definition.

class Student:
    Statement-1
    Statement-1
    ....
    ....
    ....
    Statement-n

A class definition started with the keyword 'class' followed by the name of the class and a colon.

The statements within a class definition may be function definitions, data members or other statements.

When a class definition is entered, a new namespace is created, and used as the local scope.

Creating a Class:

Here we create a simple class using class keyword followed by the class name (Student) which follows an indented block of segments (student class, roll no., name).

#studentdetails.py
class Student:
        stu_class = 'V'
        stu_roll_no = 12
        stu_name = "David"

Class Objects:

There are two kind of operations class objects supports : attribute references and instantiation. Attribute references use the standard syntax, obj.name for all attribute references in Python. Therefore if the class definition (add a method in previous example) look like this

#studentdetails1.py
class Student:
    """A simple example class"""
    stu_class = 'V'
    stu_roll_no = 12
    stu_name = "David"
    def messg(self):
            return 'New Session will start soon.'

then Student.stu_class, Student.stu_roll_no, Student.stu_name are valid attribute reference and returns 'V', 12, 'David'. Student.messg returns a function object. In Python self is a name for the first argument of a method which is different from ordinary function. Rather than passing the object as a parameter in a method the word self refers to the object itself. For example if a method is defined as avg(self, x, y, z), it should be called as a.avg(x, y, z). See the output of the attributes in Python Shell.

Python class attribute example

__doc__ is also a valid attribute which returns the docstring of the class.

__init__ method:

There are many method names in Python which have special importance. A class may define a special method named __init__ which does some initialization work and serves as a constructor for the class. Like other functions or methods __init__ can take any number of arguments. The __init__ method is run as soon as an object of a class is instantiated and class instantiation automatically invokes __init__() for the newly-created class instance. See the following example a new, initialized instance can be obtained by:

#studentdetailsinit.py
class Student:
    """A simple example class"""
    def __init__(self, sclass, sroll, sname):
        self.c = sclass
        self.r = sroll
        self.n = sname
    def messg(self):
            return 'New Session will start soon.'
python class init method

Operators

Addition:

class School:
    def __init__(self, *subjects):
        self.subjects = list(subjects)

class Subject:
    
    def __add__(self, other):
        return School(self, other)
F1, F2 = Subject(), Subject()
F1 + F2

Output:

<__main__.School object at 0x0000000008B82470>
from pathlib import Path
path = Path('.').parent / 'data'
path.absolute()

Output:

WindowsPath('C:/Users/User/AppData/Local/Programs/Python/Python37/data')

Greater / Equality:

class Person:
    '''person entity'''

    def __init__(self, first_name, surname, age):
        self.first_name = first_name
        self.surname = surname
        self.age = age
    
    def __repr__(self):
        return f'Person(first_name={self.first_name}, surname={self.surname}, age={self.age})'        

    def __lt__(self, other):
        return self.age < other.age
data = [
    {'first_name':"John", 'surname':'Smith', 'age':13},
    {'first_name':"Anne", 'surname':'McNell', 'age':11},
    {'first_name':'Mary', 'surname': 'Brown', 'age':14}
]

results = [Person(**row) for row in data]
print(results)

Output:

[Person(first_name=John, surname=Smith, age=13), 
Person(first_name=Anne, surname=McNell, age=11),
Person(first_name=Mary, surname=Brown, age=14)]

Length:

class School:
    def __init__(self, *subjects):
        self.subjects = list(subjects)
    
    def __len__(self):
        return len(self.subjects)
Sub = School(Subject(), Subject())
print(len(Sub))

Output:

2

Getitem:

class School:
    def __init__(self, *subjects):
        self.subjects = list(subjects)

    def __getitem__(self, i):
        return self.subjects[i]
Sub = School(Subject(), Subject())
print(Sub[0])

Output:

<__main__.Subject object at 0x0000000007ACC5F8>

Inheritance:

The concept of inheritance provides an important feature to the object-oriented programming is reuse of code. Inheritance is the process of creating a new class (derived class) to be based on an existing (base class) one where the new class inherits all the attributes and methods of the existing class. Following diagram shows the inheritance of a derived class from the parent (base) class.

python inheritance diagram

Like other object-oriented language, Python allows inheritance from a parent (or base) class as well as multiple inheritances in which a class inherits attributes and methods from more than one parent. See the single and multiple inheritance syntaxes :

class DerivedClassName(BaseClassName):
    Statement-1
    Statement-1
    ....
    ....
    ....
    Statement-n

class DerivedClassName(BaseClassName1, BaseClassName2, BaseClassName3):
    Statement-1
    Statement-1
    ....
    ....
    ....
    Statement-n

Example:

In a company Factory, staff and Office staff have certain common properties - all have a name, designation, age etc. Thus they can be grouped under a class called CompanyMember. Apart from sharing those common features, each subclass has its own characteristic - FactoryStaff gets overtime allowance while OfficeStaff gets traveling allowance for an office job. The derived classes ( FactoryStaff & OfficeStaff) has its own characteristic and, in addition, they inherit the properties of the base class (CompanyMember). See the example code.

# python-inheritance.py
class CompanyMember:
	'''Represents Company  Member.'''
	def __init__(self, name, designation, age):
		self.name = name
		self.designation = designation
		self.age = age
	def tell(self):
		'''Details of an employee.'''
		print('Name: ', self.name,'\nDesignation : ',self.designation, '\nAge : ',self.age)

class FactoryStaff(CompanyMember):
	'''Represents a Factory Staff.'''
	def __init__(self, name, designation, age, overtime_allow):
		CompanyMember.__init__(self, name, designation, age)
		self.overtime_allow = overtime_allow
		CompanyMember.tell(self)
		print('Overtime Allowance : ',self.overtime_allow)

class OfficeStaff(CompanyMember):
	'''Represents a Office Staff.'''
	def __init__(self, name, designation, age, travelling_allow):
		CompanyMember.__init__(self, name, designation, age)
		self.marks = travelling_allow
		CompanyMember.tell(self)
		print('Traveling Allowance : ',self.travelling_allow)

Now execute the class in Python Shell and see the output.

python inheritance

 

Previous: calendar()
Next: Python Built-in Functions

Test your Python skills with w3resource's quiz



Follow us on Facebook and Twitter for latest update.