What is the purpose of a callable object? What problems do they solve?
There are areas, especially in the 'functions calling functions of function functions' where objects allow less nesting.
Consider making a classic decorator that checks an authorization level before calling a function. Using it is clear:
@check_authorization(level="Manager")
def update_price(Item, new_price):...
You could do this as nested functions:
def check_authorization(level):
def take_params(function):
def concrete(*args, **kwargs):
if user_level_greater_than(level):
return function(*args,
**kwargs)
return None
return concrete
return take_params
Or you could to this as a class, which might be clearer:
class check_authorization(object):
def __init__(level):
self.level = level
def __call__(function):
self.function = function
return self.dec
def dec(self, *args, **kwargs):
if user_level_greater_than(self.level):
return self.function(*args,v**kwargs)
return None
Many would find this flat method more clear. Of course, I believe in cheating, because I like the signatures and metadata correct:
from dectools.dectools import make_call_if
@make_call_if
def check_authorization(function, arg, kwargs, level):
return user_level_greater_than(level)
The callable object is a tool which is good for some known applications and may also be good for the bizarre problem real life throws at you.