
On Sun, Apr 17, 2016 at 1:26 PM, Random832 <random832@fastmail.com> wrote:
On Sat, Apr 16, 2016, at 22:50, Chris Angelico wrote:
def __getattr__(self, name): if '__getattr__' in self.__dict__: return self.__dict__['__getattr__'](name) raise AttributeError
The biggest downside I'm seeing is that module attributes double as global names, which might mean this would get checked for every global name that ends up being resolved from the builtins (which is going to be a LOT). But I'm not sure if that's even true.
It is not. (Also, incidentally, defining a global called __class__ does not set the module's class.)
I don't think this would be enough alone to let you use property decorators on a module - you'd have to explicitly define a __getattr__ (and __setattr__). And of course make sure that the names you're using as properties don't exist as real members of the module, since you're using __getattr__ instead of __getattribute__.
Right, it wouldn't automatically allow the use of properties *as such*, but you would be able to achieve most of the same goal. # Version 1 BITS_PER_BYTE = 8 BITS_PER_WORD = 32 # Version 2 - doesn't work BITS_PER_BYTE = 8 @property def BITS_PER_WORD(): return 32 or 64 # Version 3 - could work BITS_PER_BYTE = 8 def __getattr__(name): if name == 'BITS_PER_WORD': return 32 or 64 raise AttributeError It's not as clean as actually supporting @property, but it could be done without the "bootstrap problem" of trying to have a module contain the class that it's to be an instance of. All you have to do is define __getattr__ as a regular top-level function, and it'll get called. You can then dispatch to property functions if you wish (eg """return globals()['_property_'+name]()"""), or just put all the code straight into __getattr__. ChrisA