built-in functions as class attributes

Peter Otten __peter__ at web.de
Mon Dec 8 12:23:58 CET 2008


Mark Dickinson wrote:

> Here's a curiosity:  after
> 
> def my_hex(x):
>     return hex(x)
> 
> one might expect hex and my_hex to be interchangeable
> in most situations.  But (with both Python 2.x and 3.x)
> I get:
> 
>>>> def my_hex(x): return hex(x)
> ...
>>>> class T(object): f = hex
> ...
>>>> class T2(object): f = my_hex
> ...
>>>> T().f(12345)
> '0x3039'
>>>> T2().f(12345)
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> TypeError: my_hex() takes exactly 1 argument (2 given)
> [36412 refs]
> 
> Anyone know what the precise rules that lead to this
> behaviour are, or where they're documented?

To work properly as a method a callable needs a __get__() method
implementing the binding mechanism. Functions written in C generally don't
have that.

>>> class A(object):
...     def __call__(self, *args):
...             print "called with", args
...
>>> class B(object):
...     a = A()
...
>>> B().a()
called with ()

Now let's turn A into a descriptor:

>>> def __get__(self, inst, cls=None):
...     print inst, cls
...     if inst is not None:
...             def bound(*args):
...                     self(inst, *args)
...             return bound
...     return self
...
>>> A.__get__ = __get__
>>> B().a()
<__main__.B object at 0x2ae49971b890> <class '__main__.B'>
called with (<__main__.B object at 0x2ae49971b890>,)

I don't know if there is something official, I google for

http://users.rcn.com/python/download/Descriptor.htm

or "descrintro" every time I need a refresher.

Peter




More information about the Python-list mailing list