This recipe shows a simple way of implementing callbacks in Python. There are a few ways this can be done. The way shown here uses a simple function-based approach.
In a nutshell, a callback can be informally described like this: function a calls function b, and wants to make b run a specific independent chunk of code at some point during b's execution. We want to be able to vary which chunk of code gets called in different calls to b, so it cannot be hard-coded inside b. So function a passes another function, c, to b, as one argument, and b uses that parameter c to call the functionality that a wants b to call. (Function b may pass some parameters to the function represented by c, when it calls it. These could be either internally generated, passed from a, or a combination of both). So, by changing the value of the function c that gets passed to b (on different calls to b), a can change what chunk of code b calls.
More details and full code, description and output here:
https://jugad2.blogspot.in/2017/04/implementing-and-using-callbacks-in.html
Don't have Python Installed?
Install Python along with this recipe!
After Installation
- Edit the recipe.py file to modify the recipe.
- Run
state run recipe
to run the recipe and see your changes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | # File: callback_demo.py
# To demonstrate implementation and use of callbacks in Python,
# using just plain functions.
# Author: Vasudev Ram
# Copyright 2017 Vasudev Ram
# Web site: https://vasudevram.github.io
# Blog: https://jugad2.blogspot.com
# Product store: https://gumroad.com/vasudevram
from __future__ import print_function
from time import sleep
def callback_a(i, result):
print("Items processed: {}. Running result: {}.".format(i, result))
def square(i):
return i * i
def processor(process, times, report_interval, callback):
print("Entered processor(): times = {}, report_interval = {}, callback = {}".format(
times, report_interval, callback.func_name))
# Can also use callback.__name__ instead of callback.func_name in line above.
result = 0
print("Processing data ...")
for i in range(1, times + 1):
result += process(i)
sleep(1)
if i % report_interval == 0:
# This is the call to the callback function
# that was passed to this function.
callback(i, result)
processor(square, 20, 5, callback_a)
|
This is a run of the program and its output:
And here is the output when I run it:
$ python callback_demo.py
Entered processor(): times = 20, report_interval = 5, callback = callback_a
Processing data ...
Items processed: 5. Running result: 55.
Items processed: 10. Running result: 385.
Items processed: 15. Running result: 1240.
Items processed: 20. Running result: 2870.
$
We can see that the callback gets called as desired, at intervals, to report the progress of the work being done by the processor function.
If we passed a different function as the last argument to processor, say, callback_b, we could get processor to report the progress in a different way, without changing the code of the processor function itself. This leads to code with less coupling, which is generally preferable for modularity and maintainability.
More details and full code and output here:
https://jugad2.blogspot.in/2017/04/implementing-and-using-callbacks-in.html