[Python-ideas] Fix that broken callable builtin

Terry Reedy tjreedy at udel.edu
Sat Apr 18 03:04:56 CEST 2015


On 4/17/2015 5:19 PM, Ionel Cristian Mărieș wrote:
> __add__ as a property/descriptor seems to work fine, eg:
>
>      >>> class C:
>     ...  @property
>     ...  def __add__(self):
>     ...   return lambda other: [self, other]
>     ...
>      >>> C() + C()
>     [<__main__.C object at 0x0000000003652AC8>, <__main__.C object at
>     0x0000000003652CC0>]
>
>
> Am I missing something?

An instance method is neither a class method nor a static method.  It is 
also not a property.  In your example above, __add__ is a property and 
not an instance method.  This violate the Reference Manual definition of 
the reserved name '__add__' as an instance method.

If f is an one-parameter instance method of class C and c is an instance 
of C, c.f() == C.f(c).  This is not true for a property f, as C.f is not 
callable, and c.f is only callable if the value of the property is callable.

--
What you have done above is to curry what is intended to be a binary 
instance method into a pair of functions, with the outer, 
function-returning function getting the original name.  Having this 
curried pair implement the binary operator is quite clever.

It works because CPython apparently implements c1 + c2, at least for 
user class instances, as c1.__add__(c2), instead of the presumed 
equivalent C.__add__(c1, c2).  c1.__add__ is normally a bound method 
with c1 and C.__add__ as attributes.  c1.__add__(c2) then calls 
C.__add__(c1, c2).

In your example, c1.__add__ is a unary function with a captured nonlocal 
object. Calling it with a second object combines (adds) the two objects. 
  The possibility of @property making this work is new to me.

-- 
Terry Jan Reedy




More information about the Python-ideas mailing list