Does anybody have a good example of a Functor in Python?
When you say "functor" are you using the term in the C++ sense (i.e. a callable object) or something else?
And would a good example be the most simple one that shows you how to create one or something that shows you where they'd be useful?
Here is a typical example:
class Accumulator(object): ''' remembers self.n __call__() allows the class instance to be called as a function ''' def __init__(self, n=0): self.n = n def __call__(self, x): self.n += x return self.n # create an instance and initialize data = 4 acc = Accumulator(4) # remembers 4 and adds 5 print(acc(5)) # 9 # remembers 9 and adds 2 print(acc(2)) # 11 # remembers 11 and adds 9 print(acc(9)) # 20 # a bit more complex print(acc(acc(10))) # 60
I wrote a code snippet some time ago with a base class for functors in python, click here. I use this class quite often to code reasonably-sized tasks which can be divided into smaller tasks sharing a temporary common state.
As an example, the following code defines a functor to count the number of lines of code (LOC) in the standard library.
#!/usr/bin/env python # -*-coding: utf8-*- from __future__ import (absolute_import, division, print_function, unicode_literals) __doc__ = ''' ''' from functors import functor import io, os class count_stdlib_LOC(functor): def __call__(self): result = 0 for filename in self.python_source_files(): result += sum(1 for line in io.open(filename, 'rb')) return result def python_source_files(self): root = self.get_stdlib_dir() for dir, subdirs, files in os.walk(root): for f in files: if f.endswith('.py'): yield os.path.join(dir, f) subdirs[:] = [d for d in subdirs if not d.endswith('-packages')] def get_stdlib_dir(self): from distutils.sysconfig import get_python_lib return get_python_lib(standard_lib=True) if __name__ == '__main__': print(count_stdlib_LOC()) """ my output --> 242389 """
In my model, subclassing functor creates a callable instead of a class. Every time
count_stdlib_LOC() is called, a new instance is created and the
__call__() method is executed.
The advantage of having a functor instead of a function is that the task can be split into smaller tasks ran by other methods. This provides a handy way to encapsulate helper functions. These functions can share variables stored in
self, which exist only during the execution of the task. The functor thus provides a short-lived namespace for the task.
These functors can be called recursively and different calls can be made by different threads. Object initialization is made in the
Edited by Gribouillis
The class Accumulator is an example of a functor for closure.
Another example using a typical closure function ...
''' func_functor_strip_char1.py a Python closure function mimics a functor a functor can remember initial information ''' def strip_characters(chrs): ''' a functor to strip characters in chrs from string mystr ''' def inner(mystr): return ''.join(c for c in mystr if c not in chrs) return inner # name the functor, pass initial data strip_punctuations = strip_characters(',;:.?!') s = 'Please, strip punctuations from this string!' print(strip_punctuations(s)) # name another functor strip_vowels = strip_characters('aeiouAEIOU') s2 = 'Extra special consideration is given today' print(strip_vowels(s2)) ''' result... Please strip punctuations from this string xtr spcl cnsdrtn s gvn tdy '''
I think I get the idea.