February 17, 2021

How to Create Thread in Python

In Python, threading module has a Thread class which is used for creating thread. There are two ways to create a new Thread in Python.

  1. By creating Thread instance and passing the function that has to be executed as one of the argument to the constructor of the Thread.
  2. By creating a class that extends Thread class and overrides run method.

1. Python thread creation using threading.Thread() constructor

In Python you don’t have to always create classes. You can just create a Python file with functions for some scripting purposes. In such scenario if you want to take advantage of multi-threading, threading.Thread() is the way to go (Though you can use it with classes too). You need to pass the function that has to be executed as one of the argument to the constructor of the Thread.

Full constructor call with all the arguments is as given below-

threading.Thread(group=None, target=None, name=None, 
           args=(), kwargs={}, *, daemon=None)

This constructor should always be called with keyword arguments. Arguments are:

  • group should be None. This argument is reserved for future extension
  • target is the function that has to be invoked. Defaults to None, meaning nothing is called.
  • name is the thread name. By default, a unique name is constructed of the form “Thread-N” where N is a decimal number.
  • args is the argument passed to the target function. It is passed as a tuple. Defaults to ().
  • kwargs is a dictionary of keyword arguments passed to the target function. Defaults to {}.
  • daemon if set to True runs the thread as a daemon thread. If None (the default), the daemonic property is inherited from the current thread.

Let us write a Python program to understand how to create thread using threading.Thread(). In the example there are two functions and three threads are spawned.

import threading

def print_thread_info():
  print('Thread Name: ' + threading.current_thread().name)

def add(a, b):
  result = a + b
  print('Thread Name: ' + threading.current_thread().name + ' Sum is', result)


if __name__ == "__main__":
  # Creating threads
  t1 = threading.Thread(target=print_thread_info)
  t2 = threading.Thread(target=add, name='MyThread-1', args=(4, 5))
  t3 = threading.Thread(target=add, name='MyThread-2', args=(19, 28))
  # starting threads
  t1.start()
  t2.start()
  t3.start()
Output
Thread Name: Thread-1
Thread Name: MyThread-1 Sum is  9
Thread Name: MyThread-2 Sum is  47

In the program points to note are-

  • Since you are using multi-threading so threading module has to be imported.
    import threading
    
  • In the first instance target function is print_thread_info no other argument is passed so defaults will be used for other arguments.
  • For the other two Thread instances target function is sum, argument to the function are passed using args and thread name is also passed.
  • To start thread’s activity start() method has to be invoked on a thread. Once the thread is started it arranges for the object’s run() method to be invoked in a separate thread of control.
  • run() method invokes the callable object passed to the object’s constructor as the target argument.

2. Python thread creation using threading.Thread() constructor where methods of a class is invoked

As mentioned above you can also use threading.Thread() constructor where target is a method of a class. In that case you will have to create object of the class and pass object_name.method_name as target. In the example there is a class ThreadDemo with two methods. Then an object obj of the class is created so the target can be specified as obj.print_thread_info or obj.sum

import threading

class ThreadDemo:

    def print_thread_info(self):
        print('Thread Name: ' + threading.current_thread().name)

    def add(self, a, b):
        result = a + b
        print('Thread Name: ' + threading.current_thread().name + ' Sum is', result)


obj = ThreadDemo()
t1 = threading.Thread(target=obj.print_thread_info)
t2 = threading.Thread(target=obj.add, name='MyThread-1', args=(4, 5))
t3 = threading.Thread(target=obj.add, name='MyThread-2', args=(19, 28))
# starting threads
t1.start()
t2.start()
t3.start()
Output
Thread Name: Thread-1
Thread Name: MyThread-1 Sum is 9
Thread Name: MyThread-2 Sum is 47

3. Python Thread creation using class that extends Thread class

You can create a class extending Thread class which makes your class also of type Thread. In your subclass override the run() method of the Thread class and provide the functionality that you want to be executed by the threads. When you will create instance of your class (which is also of type Thread because of inheritance) and call start() method, threads will execute the overridden run() method of this class.

import threading

# inherit from Thread class
class MyThread(threading.Thread):
    def __init__(self, msg):
        # Calling Thread class constructor
        super().__init__()
        self.msg = msg

    def run(self):
        print('Message is- ' + self.msg)

# Creating thread
t1 = MyThread('Executing Thread')
t2 = MyThread('Executing Another Thread')
# starting thread
t1.start()
t2.start()
Output
Message is- Executing Thread
Message is- Executing Another Thread

In the program points to note are-

  • Thread class is extended by the class so MyThread class inherits class members of Thread class.
  • run() method is overridden and that is where you write the logic that has to be executed by a thread.
  • In the constructor (__init__()) super() function is used to call parent class constructor.
  • When you create instance of your MyThread class those objects are also of type Thread as Thread class is the parent class.
  • To start thread’s activity start() method has to be invoked on a thread which arranges for the object’s run() method to be invoked in a separate thread of control. The start() method must be called at most once per thread object.

That's all for the topic How to Create Thread in Python. If something is missing or you have something to share about the topic please write a comment.


You may also like

February 16, 2021

Python Multi-threading Tutorial

In this tutorial we’ll see the support for multi-threading in Python.

What is multi-tasking

In concurrent programming there are two types of multitasking-

  1. Process based multitasking
  2. Thread based multitasking

Process based multitasking

We run a lot of processes simultaneously on our computer for example working on a word document while playing songs and also having some sites opened in a browser. This is an example of running separate processes concurrently. Here just to clarify it, with a single processor only a single process is executed by a processor at any given time. Processor divides its execution time between different processes and executes them for the given time slice, that’s why term "time slicing" is also used.

For example if there are three processes loaded into memory and all of them have to be executed then processor may divide 1 millisecond into the slices of 1/3 millisecond each and execute them in parallel, though the context switching between processes happen so fast that as a user we get a feel that all the processes are running simultaneously or concurrently.

Process based multitasking

A process has a self-contained execution environment. A process has its own run-time resources like memory space so processes are considered heavyweight tasks.

Thread based multitasking

With in a same program you can have several tasks running like in a song player you can start playing a song and at the same time you can add more songs to your playlist. With in a program you can spawn separate threads to execute separate tasks. This concept of dividing a program into separate sub-tasks and using separate threads to execute these sub-tasks to make overall execution faster and your program more responsive is known as multi-threading.

Thread based multitasking

Threads are considered lightweight processes that are spawned with in a process and share its memory and processor time.

Multi-threading in Python

Python has in-built support for multi-threading programming in the form of threading module. The threading module has a Thread class which encapsulates thread functionality.

You can create a Thread object using one of the following ways-

  1. By creating Thread instance and passing the function that has to be executed as one of the argument to the constructor of the Thread.
  2. By creating a class that extends Thread class and overrides run method.

Once a thread object is created, its activity must be started by calling the thread’s start() method. This invokes the run() method in a separate thread of control.

Python thread creation example

1. In the following example we’ll call threading.Thread() to create Thread instance. We’ll create two Thread instances to show how you can pass arguments (passing argument is optional) to the target function.

import threading

def print_thread_info():
    print('Thread Name: ' + threading.current_thread().name)


def print_message(msg):
    print('From Thread: ' + threading.current_thread().name + ' Message is- ' + msg)


if __name__ == "__main__":
    # Creating threads
    t1 = threading.Thread(target=print_thread_info)
    t2 = threading.Thread(target=print_message, name='MyThread', args=('Hello I am a thread',))
    # starting threads
    t1.start()
    t2.start()
Output
Thread Name: Thread-1
From Thread: MyThread Message is- Hello I am a thread

In the program points to note are-

    • Since you are using multi-threading so threading module has to be imported.
      import threading
      
    • Thread instances are created using threading.Thread() constructor. In the first instance only target function (function to be executed by thread) is passed. In the second instance apart from target function, thread name and arguments to the target function are also passed.
    • To start thread’s activity start() method has to be invoked on a thread.

2. In the following example we’ll subclass Thread class and override run() method.

import threading

class MyThread(threading.Thread):
  def run(self):
    print('In run method Thread Name: ' + threading.current_thread().name)

# Creating thread
t1 = MyThread()
# starting thread
t1.start()
Output
In run method Thread Name: Thread-1

In the program points to note are-

  • Thread class is extended by the class so MyThread class is also of type Thread.
  • run() method is overridden and that is where you write the logic that has to be executed by a thread.
  • To start thread’s activity start() method has to be invoked on a thread which arranges for the object’s run() method to be invoked in a separate thread of control. The start() method must be called at most once per thread object.

Python Thread class methods

Some of the important methods and properties available in the Thread class are as following.

Method Description
start() Start the thread. This method must be called at most once per thread object. Once the thread is started it arranges for the object’s run() method to be invoked in a separate thread of control.
run() This method has the code that is executed by a thread. You may override this method in a subclass. If thread instance is created using threading.Thread() constructor then run() method invokes the callable object passed to the object’s constructor as the target argument.
join(timeout) This method blocks the calling thread until the thread whose join() method is called terminates
name Property that represents thread name.
setName(name) Method for setting thread name
getName() Method for getting thread name. It is recommended to use name property directly instead of these getter/setter methods.
is_alive() Returns True if the thread is alive False otherwise
daemon A boolean value indicating whether this thread is a daemon thread (True) or not (False).
isDaemon() Method for getting if the thread is a daemon thread or not. Returns True if it is False otherwise.
setDaemon(flag) Setting a thread as a daemon thread by passing True. It is recommended to use daemon property directly rather than these getter/setter methods.

Main thread in Python

When you write a Python program, Python Virtual Machine (PVM) starts a new thread to execute the statements in your program. Which means whenever any Python program is executing one thread is always started that thread is known as main thread in Python. Following example prints the name of currently executing thread.

import threading

def print_info():
    print('Thread Name: ' + threading.current_thread().name)

print_info()
Output
Thread Name: MainThread

As you can see in the program no thread is created explicitly still MainThread is started.

There is also a threading.main_thread() method (available Python 3.4 onward) which returns the main thread object.

import threading

def print_info():
    #print('Thread Name: ' + threading.current_thread().name)
    if threading.current_thread() is threading.main_thread():
        print('Current thread is main thread')

print_info()
Output
Current thread is main thread

That's all for the topic Python Multi-threading Tutorial. If something is missing or you have something to share about the topic please write a comment.


You may also like

February 10, 2021

Python Classes and Objects

In this tutorial you will learn how to define a class in Python and how to create an object of a class in Python.

Class in Python

A class in any object oriented programming language provides a blueprint for a new type. A class encapsulates both data and functionality together which means a class in Python can contain variables and function definition that can manipulate those variables.

Syntax for creating class in Python

To create a class use keyword class followed by class name-

class ClassName(BaseClassName):
  '''doc string describing what the class is about'''
  class variables
  def __init__(self):
  def method1(self):
  def method2(self):

If class is extending any class then that class name is given in parenthesis. If class is not extending any other class then parenthesis are not required.

class ClassName:

A doc string written using triple double quotes or triple single quotes gives information about the class. It is optional.

Class variables are variables shared by all the instances of the class. Class variables should be defined outside the scope of any class method definitions.

__init__() is a special function that acts as a construcotr of the class. When an object of the class is created __init__() is invoked automatically to initialize the object.

method1(self), method2(self) are methods in the class.

First argument of a method is called self and it is a reference to the current instance of the class. This is nothing more than a convention, self is not a keyword in Python you can name it whatever you want but it is not advisable as by not following the convention your code may be less readable to other Python programmers.

Python class example

Here is a class Employee that specifies attributes emp_id, name and age and a method display_info() that prints the value of those attributes.

class Employee:
  def __init__(self, emp_id, name, department):
    self.emp_id = emp_id
    self.name = name
    self.department = department

  def display_info(self):
    print('Id:', self.emp_id)
    print('Name:', self.name)
    print('Department:', self.department)

Object in Python

Once you have a class definition you can create objects (instances) of that class. Class provides a blueprint; what attributes and methods should be there whereas object is an entity with actual values and a place in memory.

An object has state and behavior. Values given to the attributes give object its state and its behavior is specified by the methods that can modify its state.

Syntax for creating an object in Python-

obj = ClassName()

Python object creation example

We’ll take the same class as defined above and create two objects of that class.

class Employee:
  def __init__(self, emp_id, name, department):
    self.emp_id = emp_id
    self.name = name
    self.department = department

  def display_info(self):
    print('Id:', self.emp_id)
    print('Name:', self.name)
    print('Department:', self.department)


emp1 = Employee(1, 'Renee', 'HR')
emp2 = Employee(2, 'Jerry', 'IT')
emp1.display_info()
emp2.display_info()
Output
Id: 1
Name: Renee
Department: HR
Id: 2
Name: Jerry
Department: IT

Here objects are created in these statements

emp1 = Employee(1, 'Renee', 'HR') emp2 = Employee(2, 'Jerry', 'IT')

For each object __init__() function is called to initialize the object (set values for the attributes). Both of the objects are of type Employee but have their separate states which can be seen by invoking the display_info() method on each object.

Once you create an object of a class in Python, memory for that object is allocated on the heap. Reference to that memory is stored in variable, emp1 and emp2 in the example. Following image illustrates the memory allocation for the object and how that memory is referenced.

Python class and object

Class and instance variables

Instance variables are the variables unique to each instance of the class where as class variables are the variables shared by each instance. In the Employee class we’ll add a class variable to keep track of the number of objects created.

class Employee:
  no_of_objects_created = 0
    
  def __init__(self, emp_id, name, department):
    self.emp_id = emp_id
    self.name = name
    self.department = department
    # Accessing class variable
    Employee.no_of_objects_created += 1

  def display_info(self):
    print('Id:', self.emp_id)
    print('Name:', self.name)
    print('Department:', self.department)


emp1 = Employee(1, 'Renee', 'HR')
emp2 = Employee(2, 'Jerry', 'IT')
emp1.display_info()
emp2.display_info()
print('Total number of objects created- ', Employee.no_of_objects_created)
Output
Id: 1
Name: Renee
Department: HR
Id: 2
Name: Jerry
Department: IT
Total number of objects created-  2

That's all for the topic Python Classes and Objects. If something is missing or you have something to share about the topic please write a comment.


You may also like

February 8, 2021

Abstract Class in Python With Examples

In this tutorial you will learn about Abstract class which is an important concept in object oriented programming and how to define abstract classes in Python using abc module.

What is an Abstract class

An abstract class is a class that contains one or more abstract methods. Abstract methods are methods without any body so a sub-class that extends the abstract class has to provide implementation for the abstract methods.

Creating Abstract class in Python

Abstract class in Python is created by extending the ABC meta class which is the part of abc (Abstract Base Class) module.

from abc import ABC
Class MyClass(ABC):

Abstract method in Python

Abstract method is a method that is annotated with @abstractmethod decorator. Decorator @abstractmethod has to be imported from abc module.

Syntax of Abstract class with an abstract method

from abc import ABC, abstractmethod
Class MyClass(ABC):
 @abstractmethod
 def mymethod(self):
  pass

Why use an Abstract class

Using Abstract class helps in reducing code duplication. You can create a hierarchical structure where parent class (which is defined as an abstract class) contains implementation of the methods which are going to be common for the child classes and leave what may differ as abstract methods. When child classes extend the parent class they can implement the abstract methods as per their required functionality.

Abstract class Python example

Suppose you have to design payment functionality where you have to provide functionality for cash and credit card payment and you need to capture customer details like name, address.

Here capturing customer details is common but the mode of payment is different. In this scenario you can create an abstract class with abstract doPayment() method which has to be implemented by the sub classes and keep the functionality to capture and print customer details as a concrete method in abstract class to be used by all the sub classes.

from abc import ABC, abstractmethod

class Payment(ABC):
  def __init__(self, customer_name, customer_address):
    self.customer_name = customer_name
    self.customer_address = customer_address

  def print_customer_info(self):
    print('Customer Name:', self.customer_name)
    print('Customer Address:', self.customer_address)

  @abstractmethod
  def do_payment(self, amount):
    pass

class CreditPayment(Payment):
  def __init__(self, customer_name, customer_address):
    super().__init__(customer_name, customer_address)

  def do_payment(self, amount):
    print('In child class CreditPayment, payment of-', amount)
    super().print_customer_info()

class CashPayment(Payment):
  def __init__(self, customer_name, customer_address):
    super().__init__(customer_name, customer_address)

  def do_payment(self, amount):
    print('In child class CashPayment, payment of-', amount)
    super().print_customer_info()


# object of Child class
obj = CreditPayment("Ryan", "5th ave, NYC")
obj.do_payment(34.56)
obj = CashPayment("Nina", "Burnsville, NC")
obj.do_payment(12.23)
Output
In child class CreditPayment, payment of- 34.56
Customer Name: Ryan
Customer Address: 5th ave, NYC
In child class CashPayment, payment of- 12.23
Customer Name: Nina
Customer Address: Burnsville, NC

In the example Abstract class Payment has one concrete methods print_customer_info() that is invoked from the child classes using the super() function.

Important points about Python Abstract class

Some of the important features of abstract class in Python are as following-

  1. Abstract class may contain both concrete methods as well as abstract methods. We have already seen that in the above example.
  2. Since abstract class doesn’t contain the full functionality so you can’t instantiate an abstract class. In the above example trying to create an object of Payment class (obj = Payment("Ram", "Pink street, Jaipur")) which is abstract results in an error-
        obj = Payment("Ram", "Pink street, Jaipur")
    TypeError: Can't instantiate abstract class Payment with abstract methods do_payment
    
  3. Subclass that extends the abstract class must implement all the abstract methods of the abstract class. If we have a definition as following where CashPayment class doesn’t implement the abstract method do_payment() of the parent class.
    class CashPayment(Payment):
        def __init__(self, customer_name, customer_address):
            super().__init__(customer_name, customer_address)
    
    This results in error
    obj = CashPayment("Nina", "Burnsville, NC")
    TypeError: Can't instantiate abstract class CashPayment with abstract methods do_payment
    

That's all for the topic Abstract Class in Python With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

February 4, 2021

How to Copy File in Python

In this post we’ll see different ways you can copy a file in Python.

1. A simple way to copy a file in Python is to use read() method to read a file once you have a file object and then write the content to another file.

Following Python program opens an image file in binary mode and then writes it to another file.

def copy_file(src_file, dest_file):
  try:
    f1 = open(src_file, 'rb')
    f2 = open(dest_file, 'wb')
    b = f1.read()
    f2.write(b)
    print('Coying image completed...')
  finally:
    f1.close()
    f2.close()


#calling function
copy_file('F:/knpcode/image.png', 'F:/knpcode/Python/newimage.png')

2. Of course there are better ways in Python to copy a file. The shutil module offers a number of high-level operations on files and collections of files.

In that module there is a function shutil.copyfile(src, dest) which copies the contents of the file named src to a file named dst. Destination must be the complete target file name and it must be writable. If dst already exists, it will be replaced. Function returns the path to the destination file.

Note that this function doesn't copy the metadata (permission bits, last access time, last modification time) of the file.

def copy_file(src_file, dest_file):
    try:
        shutil.copyfile(src_file, dest_file)
        print('Copying file completed...')
    except shutil.SameFileError as error:
        print(error)
        print('source and destination files are same')
    except IOError as error:
        print(error)
        print('Destination not writable')
    # Any other exception
    except:
        print('Error while copying')

3. If you want to copy file as well as metadata (permission bits, last access time, last modification time) then use shutil.copystat(src, dst)

def copy_file(src_file, dest_file):
    try:
        shutil.copystat(src_file, dest_file)
        print('Copying file completed...')
    except shutil.SameFileError as error:
        print(error)
        print('source and destination files are same')
    except IOError as error:
        print(error)
        print('Destination not writable')
    # Any other exception
    except:
        print('Error while copying')

4. If you want to copy a source file to another directory that can be done using shutil.copy(src, dst)

Here dst may specify a directory and the file will be copied into dst using the base filename from src. Function returns the path to the newly created file.

def copy_file(src_file, dest_dir):
    try:
        file_path = shutil.copy(src_file, dest_dir)
        print('Copying file completed...', dest_dir)
    except shutil.SameFileError as error:
        print(error)
        print('source and destination files are same')
    except IOError as error:
        print(error)
        print('Destination not writable')
    # Any other exception
    except:
        print('Error while copying')

That's all for the topic How to Copy File in Python. If something is missing or you have something to share about the topic please write a comment.


You may also like