[Python-ideas] "Loose" descriptors

Steven D'Aprano steve at pearwood.info
Sun Mar 29 04:17:07 CEST 2015


On Sun, Mar 29, 2015 at 11:51:31AM +1300, Greg Ewing wrote:
> James Edwards wrote:
> >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.
> 
> This would slow down *all* lookups of global names in
> order to support a rarely-used feature. Since global
> name lookup is critical performance-wise, this is
> likely to meet a lot of resistance.
> 
> Similar arguments have been made concerning the
> support of descriptors in module namespaces, which
> is a closely related idea.

I don't think it's a closely related idea, I think it is *exactly* the 
same idea. If I've understood him correctly, James wants to use 
descriptors in global variables, i.e. module namespaces, not just class 
attributes.

You are right that making this the default behaviour would cause 
slow-down of all module-level lookups for very rare advantage, but what 
if we moved the descriptor logic into the global __dict__ instead of the 
compiler? Then, in thory at least, supporting the descriptor protocol 
for global variables will be opt-in on a per-module basis.

Here's a sketch of how you might do it.

class DescriptorDict(dict):
    def __getitem__(self, key):
        obj = super().__getitem__(key)
        if hasattr(type(obj), '__get__'):
            # I'm not sure what to pass as instance here.
            return type(obj).__get__(obj, instance)
        return obj


__dict__ = DescriptorDict(__dict__)


I'm sure there are complications I haven't even begun to imagine, but 
here are a few obvious ones:

(1) Can modules use a dict subclass for __dict__? 
(2) Can you replace the __dict__ on the fly like this?
(3) If not, how do you bootstrap the module to have a magic dict instead 
    of an ordinary dict?
(4) The descriptor protocol expects to pass the instance and/or class 
    to the __get__ method, as well as `self`. self is the descriptor 
    itself; what is instance? The module?


I don't know if it can be done, but if it could be, it would certainly 
open the doors for a lot of interesting experiments.



-- 
Steve


More information about the Python-ideas mailing list