Saturday 11 July 2009

Background to Python functools module

To know the intellectual history of functools development read this (PEP309).
>>> import functools
>>> dir(functools)
['WRAPPER_ASSIGNMENTS', 'WRAPPER_UPDATES', '__builtins__', '__doc__', '__file__', '__name__', 'partial', 'update_wrapper', 'wraps']

Python: Old Style and New Style Classes and an Ode to Moses Schonfinkel

If I define a class C and function called static_method() and do C.static_method() the result is TypeError. static_method has become a special kind of method object, called an unbound-method object, not a plain function. When you call a method on an object, the first argument is self, and here self returns null. How does one avoid this problem?

The key difference is to understand the difference between function objects and the more general notion of "callables". "Mutation to unbound method objects" only happens to function objects not other "Callables". If we don't want mutation to occur, we must use a Callable that is not a function object, as follows:

class Callable:
def __init__(self, anycallable):
self.__call__ = anycallable


We create an instance of Callable which delegates calls to another Callable it holds.Class methods can then be implemented in the enclosing class as instances of Callable.

class ClassWithStaticMethod:
def staticMethod(name):
print "Hi there",name
staticMethod = Callable(Method)


Of course, an easier solution is to use the @staticmethod decorator to your function.

Lots of good stuff has been written by this man, Alex Martelli from Google, formerly of Open End AB, a Python-oriented software house in Gothenburg, Sweden. For example, check out this recipe on high-performance currying in Python. Haskell Curry (whose name the verb currying is derived) was a writer and teacher of mathematical logic and creator of the lambda calculus of combinatory logic. His intellectual predecessor was Moses Schonfinkel, a Russian logician, and the German mathematican David Hilbert.

Back to old style and new style classes in Python. For old style classes, type(instance variable x) returns "instance" as the type, whereas type(x) for new style classes returns __class__ attribute. To quote the Python documentation, "new-style classes were introduced in Python 2.2 to unify classes and types". Benefits of this approach include the ability to subclass most built-in types. Essentially, new style classes are old style classes with RTTI support.

Taken from the docs: "For compatibility reasons, classes are still old-style by default. New-style classes are created by specifying another new-style class (i.e. a type) as a parent class, or the “top-level type” object if no other parent is needed".

To understand more deeply what Guido alludes to when talking of type/class unification read his explanatory essay.