A functor, or function object is sometimes a convenient way to encapsulate helper functions and data needed to achieve a small task, and also to share data between calls to the same function. This snippet defines a base class [b]functor[/b] which permits an easy functor creation for python 2.
A base class to define functors.
# python 2.7
# functors.py
import sys
__version__ = '0.0.2'
__all__ = ["functor", "staticfunctor", "classfunctor"]
class metafunctor(type):
wrapmore = staticmethod(lambda f: f)
"""helper metaclass for functors"""
def __new__(meta, class_name, bases, new_attrs):
if "__init__" in new_attrs:
raise TypeError("__init__() forbidden in functor class '%s'" % class_name)
klass = type.__new__(meta, class_name, bases, new_attrs)
def wrapper(*args, **kwd):
return klass()(*args, **kwd)
wrapper = meta.wrapmore(wrapper)
from functools import update_wrapper
update_wrapper(wrapper, klass)
wrapper._functor_class = klass
return wrapper
class metastaticfunctor(metafunctor):
wrapmore = type('_staticmethod', (staticmethod,), dict())
class metaclassfunctor(metafunctor):
wrapmore = type('_classmethod', (classmethod,), dict())
class functor(object):
"""A base class to define functors, a special kind of function objects.
Author: Gribouillis, for the python forum at www.daniweb.com
License: This program has been placed in the public domain
Created and published June the 27th 2011
Tests: tests can be run on the command line with 'python -m doctest -v Functor.py'
Usage:
Subclassing functor defines a function instead of a class, for example
class myfunction(functor):
def __call__(self, what):
print "called with argument", repr(what)
myfunction("hello world") # myfunction is now a function and not a class
Each time myfunction is called, a *new* instance of the hidden class is created and
the instance's __call__ method is called instead. The hidden class itself can be accessed
as myfunction._functor_class.
The benefit of defining functors instead of functions is to encapsulate helper data
and methods for the task executed by the function. Here is a more complete example
of a functor to reverse the letters in each word of a sentence
>>> class reverse_words(functor):
... 'A functor to reverse words in a sentence.'
... def __call__(self, sentence):
... return self.regex.sub(self.subf, sentence)
... import re
... regex = re.compile(r'[a-zA-Z_]\w*')
... def subf(self, match): # helper functions and data are encapsulated in the functor
... return match.group(0)[::-1]
>>> print reverse_words("please reverse words in this test sentence.")
esaelp esrever sdrow ni siht tset ecnetnes.
"""
__metaclass__ = metafunctor
__slots__ = ()
def __call__(self, *args, **kwd):
raise NotImplementedError(
("__call__() not implemented for functor", self.__class__.__name__))
if sys.version_info >= (3,):
exec("""class functor(functor, metaclass = metafunctor):
__slots__ = ()""")
functor = functor._functor_class
class staticfunctor(functor):
__metaclass__ = metastaticfunctor
__slots__ = ()
staticfunctor = staticfunctor._functor_class
class classfunctor(functor):
__metaclass__ = metaclassfunctor
__slots__ = ()
classfunctor = classfunctor._functor_class
TrustyTony 888 ex-Moderator Team Colleague Featured Poster
Gribouillis 1,391 Programming Explorer Team Colleague
matricol -8 Junior Poster in Training
Gribouillis 1,391 Programming Explorer Team Colleague
Gribouillis 1,391 Programming Explorer Team Colleague
TrustyTony 888 ex-Moderator Team Colleague Featured Poster
Gribouillis 1,391 Programming Explorer Team Colleague
TrustyTony 888 ex-Moderator Team Colleague Featured Poster
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.