extending method descriptors

Michael Sliczniak msliczniak at gmail.com
Fri Jun 26 07:09:32 EDT 2009

On Jun 25, 2:30 pm, Carl Banks <pavlovevide... at gmail.com> wrote:

Thank you for the very good reply. In fact delegating is the approach
that works. The main thing to notice is that for an uninstantiated
class the first arg to __get__ is None:

class desc(object):
        __slots__ = ('x')

        def __init__(self, desc):
                self.x = desc

        def __get__(self, a, b):
                #print 'desc get', `self`, `a`, `b`

                if a == None:
                        return self

                return self.x.__get__(a)

        def __set__(self, a, b):
                #print 'desc set', `self`, `a`, `b`

                self.x.__set__(a, b)

        def foo(self):
                return 'foo'

        def bar(self):
                return 'bar'

class A(object):
        __slots__ = ('x', 'y')
        def __init__(self, *args):
                for i in xrange(len(args)):
                        setattr(self, A.__slots__[i], args[i])

a = A(0, 1)
b = A(2, 3)

print a.x, a.y, b.x, b.y

x = A.x
dx = desc(x)
A.x = dx

y = A.y
dy = desc(y)
A.y = dy

print type(a).x.foo()
print type(a).x.bar()
print type(a).y.foo()
print type(a).y.bar()
print type(b).x.foo()
print type(b).x.bar()
print type(b).y.foo()
print type(b).y.bar()

print a.x, a.y, b.x, b.y

a.x = -1
a.y = -2
b.x = -3
b.y = -4

print a.x, a.y, b.x, b.y

A.x = x

print a.x, a.y, b.x, b.y

This produces this output:

0 1 2 3
0 1 2 3
-1 -2 -3 -4
-1 -2 -3 -4

The manner in which __get__ has to delegate is not pleasant compared
to if you could simply derive a new class from method_descriptor with
the foo and bar methods though, oh well.

More information about the Python-list mailing list