[Python-ideas] "Loose" descriptors

James Edwards jheiv at jheiv.com
Sat Mar 28 23:35:17 CET 2015


(I apologize in advance if this was covered previously or elsewhere; a
fairly thorough search didn't yield anything.)

Currently, we can implement a descriptor as follows:

    class VerboseDescriptor(object):
        def __init__(self, init):
            self.val = init

        def __get__(self, obj, typ=None):
            print("Get is %s" % (self.val))
            return self.val

        def __set__(self, obj, val):
            print("Set to %s" % (val))
            self.val = val

    class Holder(object):
        val = VerboseDescriptor(2)


    foo = Holder()
    _ = foo.val
    foo.val = 4

Which of course works as expected, displaying:

    Get is 2
    Set to 4

But we can't achieve the same indirection without a "Holder"-type class.

That is, we can't do the following:

    class VerboseDescriptor(object):
        def __init__(self, init):
            self.val = init

        def __get__(self, obj, typ=None):
            print("Get is %s" % (self.val))
            return self.val

        def __set__(self, obj, val):
            print("Set to %s" % (val))
            self.val = val


    val = VerboseDescriptor(2)
    _ = val
    val = 4

Or rather, we can, but what might be expected (the same functionality
/ output), is not what occurs.

My understanding of the resolution of the first example is that python
looks for `val` in `foo.__dict__`, then in `Holder.__dict__`, where it
finds it, identifies that `Holder.val` implements `__get__`, and
handles the indirection accordingly.

So `foo.val = 4` ends up being something like `Holder.val.__set__(foo, 4)`.

But my question is would it make sense to be able to do this sort of
indirection for "loose" objects also, not just attributes of classes
or instances?  In other words, could descriptors be extended so that
they perform the same sort of indirection in the second example as the
first?

I envision (but with no real knowledge of the implications of this)
that just as python identifies that `val` in `Holder.__dict__`
implements `__get__`, python could similarly identify that `val` in
`globals()` (or `sys.modules[__name__].__dict__`, or wherever is more
appropriate) implements `__get__` and handle the indirection.

Of course, a syntax issue would arise if this were possible -- notably
the class definition of `Holder` would break.  So some syntax
adjustment would have to be made.  But is this reasonable / of
interest / attainable?

Thanks for your time and consideration.


More information about the Python-ideas mailing list