On Wed, Sep 13, 2017 at 2:00 PM, Nathaniel Smith <n...@pobox.com> wrote:
> On Wed, Sep 13, 2017 at 11:49 AM, Guido van Rossum <gu...@python.org> > wrote: > > > Why not adding both? Properties do have their uses as does > __getattr__. > > > > In that case I would just add __getattr__ to module.c, and add a recipe > or > > perhaps a utility module that implements a __getattr__ you can put into > your > > module if you want @property support. That way you can have both but you > > only need a little bit of code in module.c to check for __getattr__ and > call > > it when you'd otherwise raise AttributeError. > > Unfortunately I don't think this works. If there's a @property object > present in the module's instance dict, then __getattribute__ will > return it directly instead of calling __getattr__. > Hm, that's a good point. One would have to introduce some kind of convention where you can write properties with a leading _: @property def _foo(): return 42 and then a utility __getattr__ like this: def __getattr__(name): g = globals() name = '_' + name if name in g: return g[name]() raise AttributeError(...) > (I guess for full property emulation you'd also need to override > __setattr__ and __dir__, but I don't know how important that is.) > At that point maybe __class__ assignment is better. > We could consider letting modules overload __getattribute__ instead of > __getattr__, but I don't think this is viable either -- a key feature > of __getattr__ is that it doesn't add overhead to normal lookups. If > you implement deprecation warnings by overloading __getattribute__, > then it makes all your users slower, even the ones who never touch the > deprecated attributes. __getattr__ is much better than > __getattribute__ for this purpose. > Agreed. Alternatively we can have a recipe that implements @property support > using __class__ assignment and overriding > __getattribute__/__setattr__/__dir__, so instead of 'from > module_helper.property_emulation import __getattr__' it'd be 'from > module_helper import enable_property_emulation; > enable_property_emulation(__name__)'. Still has the slowdown problem > but it would work. > The emulation could do something less drastic than __class__ assignment -- it could look for globals that are properties, move them into some other dict (e.g. __properties__), and install a __getattr__ that looks things up in that dict and calls them. def __getattr__(name): if name in __properties__: return __properties__[name]() raise AttributeError(...) Still, proposals for sys.py notwithstanding, I'm worried that all of this is a solution looking for a problem. Yes, it's a cute hack. But is it art? -- --Guido van Rossum (python.org/~guido)
_______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com