Python Event-Driven programmingIn this tutorial, we will learn about Event-Driven programming and the Python module (Asyncio) that we can use to do Python Event-Driven programming. Event-Driven programmingEventually, the flow of a program depends upon the events, and programming which focuses on events is called Event-Driven programming. We were only dealing with either parallel or sequential models, but now we will discuss the asynchronous model. The programming model following the concept of Event-Driven programming is called the Asynchronous model. The working of Event-Driven programming depends upon the events happening in a program. Other than this, it depends upon the program's event loops that always listen to a new incoming event in the program. Once an event loop starts in the program, then only the events will decide what will execute and in which order. Look at the following flow chart of event loops to understand the working of events in event-driven programming: Asyncio- Python Event-Driven programming moduleThe asyncio module was added into Python in version 3.4, and it is available on all the later versions of Python. Asyncio module provides a very good infrastructure for writing concurrent code as single-threaded using the coroutines in the program. In the asyncio module of Python, following the different concepts are used while doing event-driven programming:
Let's learn about all these different concepts used by the asyncio module in detail and understand how they work while doing event-driven programming. The event loopThe event loop is a functionality of the asyncio module used to handle all the events happening in a computational program. Event loops act like round the way while the execution of the whole program is happening, and it also keeps track of the executed and new incoming events. One of the major advantages of the asyncio module is that it allows only a single event loop per process. In the asyncio module, we have some methods by which we can manage the event loop in the code. Following are such methods are provided in the asyncio module.
Now, we will look at a Python program in the following example where we will use the event loop method, i.e., get_event_loop() method. By using this method, we will print the command we give inside the event. Example: Look at the following Python program with event loops in it: Output Printing this text through the event loop Explanation: We have first imported the asyncio module in the program to use the event loops methods. After that, we have defined a default function where we gave 'loop' as a parameter and print command inside the function. We used the stop() method from event loops to stop the event. After that, we used the get_event_loop() method on the loop parameter to print the text from the default function. Then, in the call_soon() event loop method, we used the function name and parameter of a function as arguments. In last, we used run_forever() and close() event loops methods. FuturesFuture classes given in the asyncio module are compatible with the concurrent.futures methods. The future class given in the asyncio module represents the computation from the program, which is yet to be accomplished. There are some major differences between the concurrent.futures.Future and asyncio.futures.
Now, we will look at a Python program in the following example, where we will use the future class methods from the asyncio module and print the text in the output. Example: Output This text is printed using future class methods! Explanation: We have first defined a default function, i.e., 'myFunction', with future as a parameter. Inside the function, we used the sleep() method as a two-second pause for the execution. Then, we gave the text which we want to print in the result using future class methods. We used the get_event_loop method from the event loop in the program. Then, we used the future() class method on the future parameter given in the default function. Now, we can print the text in the output as we have used the future in it. To print the text in the output, we have used the try and finish method, wherein the try method, we have called the printing command, and in the finish method, we closed the loop using the close() method. CoroutinesThe concept of coroutines inside the asyncio module is very similar to the concept of coroutine in the thread object from the threading module. This concept of coroutines in the asyncio module is the generalization form of the subroutine concept. We can even suspend a coroutine during the program's execution so that the suspended coroutine will wait for external processing given by the user. The suspended coroutine will return to where it had last suspended only after the external processing was done completely. In asyncio module coroutines, we can use the following two ways that will help us to implement the coroutines in the program:
Let's understand both ways by using their implementation in a Python program. 1. @asyncio.coroutine decorator We can implement the coroutines inside the program by utilizing the generators with the asyncio module decorator, i.e., @asyncio.coroutine decorator. We can understand this implementation of coroutine with decorator through the following example. Example: Look at the following Python program: Output This text is present inside the coroutine of the asyncio module! Explanation: We have used the @asyncio.coroutine decorator after importing the asyncio module. Then, we used a default function to use the coroutine method to get the text. After that, we used the get_event_loop() method from the event loop to print the text in the output. Last, we used the 'try and finally' method on the default function and closed the loop in the program using the close() function. 2. async def function() We can say that the async def function() is the most generalized method for implementing the coroutines by the asyncio module. We can understand this method of implementing coroutines with def function() through the following example. Example: Look at the following Python program: Output This text is present inside the coroutine of the asyncio module! Explanation: Like the first way of implementing coroutines, we have followed the same path in this method too. In this method, instead of using a decorator and then defining the default function for coroutines, we have directly used the async def operationCoroutine() function of the asyncio module to implement coroutines. TasksTasks is a subclass given in the asyncio module responsible for executing asyncio coroutines inside an event loop in a parallel manner of execution. We can understand the working of tasks subclass by using a Python program to execute coroutines with it. Example Output Loop event is processing coroutine no: 0 Loop event is processing coroutine no: 1 Loop event is processing coroutine no: 2 Loop event is processing coroutine no: 3 Loop event is processing coroutine no: 4 Loop event is processing coroutine no: 5 Loop event is processing coroutine no: 6 Loop event is processing coroutine no: 7 Loop event is processing coroutine no: 8 Loop event is processing coroutine no: 9 All given tasks are completed Explanation: We have imported asyncio and time modules in the program to use its functions. Then, we used an async default function to set the task of printing processed coroutines. We used the sleep() function of the time module to give a break of 2 seconds after printing every executed coroutine. Then, we used another async default function to set the loop over tasks in it. After completing loops, the function will print 'task completed.' In last, we used the event loop method for running and closing the loop in the program. TransportsTransports are the classes provided to us in the asyncio module, and we can use them to implement various types of communication in the program. The transport classes are not thread-safe, and we always have to pair them with a protocol instance after the communication channel is established. In the asyncio transport class, the following types of transports can be inherited in the program from the base transport class:
In all the above-mentioned inherited transport classes, only the following distinct types of methods are subsequently transient from the base transport class:
ProtocolsIn the asyncio module, we are provided with several base classes which we can use to implement our network protocols in the subclasses. We can use such classes in conjunction with transport classes. The protocol will ask for the outgoing data and parses the incoming data, whereas the transport class is responsible for the buffering and actual I/O. Following are the three classes of protocols:
Next TopicPython Semaphore |