[Python-Dev] Autoloading? (Making Queue.Queue easier to use)
Nick Coghlan
ncoghlan at gmail.com
Thu Oct 13 13:41:31 CEST 2005
Greg Ewing wrote:
> BTW, I agree that special *syntax* isn't necessarily
> needed. But it does seem to me that some sort of
> hook is needed somewhere to make this doable
> smoothly, that doesn't exist today.
Having module attribute access obey the descriptor protocol (__get__, __set__,
__delete__) sounds like a pretty good option to me.
It would even be pretty backwards compatible, as I'd be hardpressed to think
why anyone would have a descriptor *instance* as a top-level object in a
module (descriptor definition, yes, but not an instance).
Consider lazy instance attributes:
Py> def lazyattr(func):
... class wrapper(object):
... def __get__(self, instance, cls):
... val = func()
... setattr(instance, func.__name__, val)
... return val
... return wrapper()
...
Py> class test(object):
... @lazyattr
... def foo():
... print "Evaluating foo!"
... return "Instance attribute"
...
Py> t = test()
Py> t.foo
Evaluating foo!
'Instance attribute'
Py> t.foo
'Instance attribute'
And lazy class attributes:
Py> def lazyclassattr(func):
... class wrapper(object):
... def __get__(self, instance, cls):
... val = func()
... setattr(cls, func.__name__, val)
... return val
... return wrapper()
...
Py> class test(object):
... @lazyclassattr
... def bar():
... print "Evaluating bar!"
... return "Class attribute"
...
Py> test.bar
Evaluating bar!
'Class attribute'
Py> test.bar
'Class attribute'
Unfortunately, that trick doesn't work at the module level:
Py> def lazymoduleattr(func):
... class wrapper(object):
... def __get__(self, instance, cls):
... val = func()
... globals()[func.__name__] = val
... return val
... return wrapper()
...
Py> @lazymoduleattr
... def baz():
... print "Evaluating baz!"
... return "Module attribute"
...
Py> baz # Descriptor not invoked
<__main__.wrapper object at 0x00B9E3B0>
Py> import sys
Py> main = sys.modules["__main__"]
Py> main.baz # Descriptor STILL not invoked :(
<__main__.wrapper object at 0x00B9E3B0>
But putting the exact same descriptor in a class lets it work its magic:
Py> class lazy(object):
... baz = baz
...
Py> lazy.baz
Evaluating baz!
'Module attribute'
Py> baz
'Module attribute'
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.blogspot.com
More information about the Python-Dev
mailing list