views:

320

answers:

3

What is their purpose? What problems do they solve?

Thanks.

+5  A: 

They take parameters and return a result depending on those parameters.

A callable is just an abstract form of a function resp an interface that defines that an object acts like a function (i.e. accepts parameters).

As functions are first class objects, it is obvious that functions are callable objects. If you are talking about the __call__ method, this is just one of the many special methods with which you can overload the behavior of custom objects, e.g. for arithmetic operations or also defining what happens if you call an object.

One idea why to use such is to have some kind of factory object that itself creates other objects.

Felix Kling
+1 : see related question: http://stackoverflow.com/questions/111234/what-is-a-callable-in-python
rmk
+5  A: 

Many kinds of objects are callable in Python, and they can serve many purposes:

  • functions are callable, and they may carry along a "closure" from an outer function
  • classes are callable, and calling a class gets you an instance of that class
  • methods are callable, for function-like behavior specifically pertaining to an instance
  • staticmethods and classmethods are callable, for method-like functionality when the functionality pertains to "a whole class" in some sense (staticmethods' usefulness is dubious, since a classmethod could do just as well;-)
  • generators are callable, and calling a generator gets you an iterator object
  • finally, and this may be specifically what you were asking about (not realizing that all of the above are objects too...!!!), you can code a class whose instances are callable: this is often the simplest way to have calls that update an instance's state as well as depend on it (though a function with a suitable closure, and a bound method, offer alternatives, a callable instance is the one way to go when you need to perform both calling and some other specific operation on the same object: for example, an object you want to be able to call but also apply indexing to had better be an instance of a class that's both callable and indexable;-).

A great range of examples of the kind of "problems they solve" is offered by Python's standard library, which has many cases of each of the specific types I mention above.

Alex Martelli
A: 

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.

Charles Merriam