[Python-ideas] descriptors outside of classes

Eric Snow ericsnowcurrently at gmail.com
Wed Mar 30 23:18:52 CEST 2011


The same could be applied to the globals if module subclassing were
practical.  Then you could just use descriptors on that subclass.  I expect
that custom import functionality could provide this right now.  Naturally,
this would affect that promise Nick was talking about regarding globals,
which could be confusing.  But only in the same way that descriptors can be
for classes already.

Even if messing with the module class's __dict__ were legal, adding
decorators there would probably not be effective since all modules would get
those attributes.  However, with module subclasses that would be more
practical.

Of course, the application of all this would be to let a module control what
happens when another module tries to use the first module's namespace.  But
that is what descriptors are all about.

-eric

On Wed, Mar 30, 2011 at 2:26 PM, Raymond Hettinger <
raymond.hettinger at gmail.com> wrote:

>
> On Mar 29, 2011, at 10:59 AM, Eric Snow wrote:
>
> > Here's another outlandish idea.  How about if descriptors could be used
> outside of classes.  I.e. any global or local variable could be assigned a
> descriptor object and the descriptor protocol would be respected for that
> variable.  This would be a pretty messy change, and I have no illusions that
> the idea will go anywhere.  However, would there be room for this in python?
>
> FWIW, you can already do this with locals (am not saying you should do it,
> am just saying that you can do it).
>
> Remember, the essential mechanism for descriptors is in the lookup
> function, not in the descriptor itself.  For example, property() objects are
> descriptors only because they define one of the descriptor protocol methods
> (__get__, et al).  Whether it gets invoked solely depends on how you look it
> up.   If you use regular dictionary lookup, a.__class__.__dict__['x'], then
> the property object is retrieved but no special action occurs.  If you use
> dotted lookup, a.x, then the property's __get__ method is called.  This is
> because the lookup function, object.__getattribute__(), has code to detect
> and invoke descriptors.
>
> A ultra-simplified version of the lookup functions's psuedo-code looks like
> this:
>
>          value = kls.__dict__[key]
>          if hasattr(value, '__get__'):
>                return call_the_getter(kls ,key)
>          else:
>                return the value
>
> Knowing this, it is possible to emulate that behavior with a dictionary
> whose lookup function, __getitem__(), can detect and invoke some sort of
> descriptor protocol.
>
> Since eval/exec can use arbitrary mappings for locals, you can use your
> custom dictionary while executing arbitrary python code.  Essentially,
> you're executing python code in an environment where the lookup function for
> locals has been trained to handle your custom descriptor protocol.
>
>
> Raymond
>
>
> ----- simple example -----
>
> class MyDict:
>    def __init__(self, mapping):
>        self.mapping = mapping
>    def __getitem__(self, key):
>        value = self.mapping[key]
>        if hasattr(value, '__get__'):
>            print('Invoking descriptor on', key)
>            return value.__get__(key)
>        print('Getting', key)
>        return value
>    def __setitem__(self, key, value):
>        self.mapping[key] = value
>
> class Property:
>    def __init__(self, getter):
>        self.getter = getter
>    def __get__(self, key):
>        return self.getter(key)
>
> if __name__ == '__main__':
>    md = MyDict({})
>    md['x'] = 10
>    md['_y'] = 20
>    md['y'] = Property(lambda key: md['_'+key])
>    print(eval('x+y+1', {}, md))
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20110330/36bd293f/attachment.html>


More information about the Python-ideas mailing list