[Python-ideas] "Loose" descriptors
Andrew Barnert
abarnert at yahoo.com
Sun Mar 29 07:36:37 CEST 2015
On Mar 28, 2015, at 19:17, Steven D'Aprano <steve at pearwood.info> wrote:
>
>> 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.
Yeah, that's how I interpreted it too.
The obvious way to do this is to provide some way for a module to define not only an instance of the module type, but a subclass and an instance of that subclass. The subclass then provides a natural place for the descriptors to live (and a natural answer to what gets passed for inst and typ).
There was a proposal for something very much like that some time late last year, IIRC, which might be worth digging up.
(Modules that don't define a subclass could still be easily optimized for fast global lookup, because the compiler knows that the base module class doesn't have any descriptors.)
> 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
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
More information about the Python-ideas
mailing list