Re: [Python-Dev] Autoloading? (Making Queue.Queue easier to use)
John Camera writes:
It sounds like he feels Queue should just be part of threading but queues can be used in other contexts besides threading. So having separate modules is a good thing.
Perhaps I am wrong here, but the Queue.Queue class is designed specifically for synchronization, and I have always been under the impression that it was probably NOT the best tool for normal queues that have nothing to do with threading. Why incur the overhead of synchronization locks when you don't intend to use them. I would advise against using Queue.Queue in any context besides threading. continued...
I guess from Gregs comments Im not sure if he wants to [...]
I'm going to stop trying to channel Greg here, he can speak for himself. But I will be quite surprised if _anyone_ supports the idea of having an module modify the local namespace importing it when it is imported. and later...
Here are 2 possible suggestions for the import statements
import Queue asneeded delayedimport Queue # can't think of a better name at this time
Woah! There is no need for new syntax here! If you want to import Queue only when needed use this (currently legal) syntax: if queueIsNeeded: import Queue If you want to add a module (call it "Queue") to the namespace, but delay executing some of the code for now, then just use "import Queue" and modify the module so that it doesn't do all its work at import time, but delays some of it until needed. That too is possible today: # start of module initialized = False def doSomething(): if not initialized: initialize() # ... Python today is incredibly dynamic and flexible... despite the usual tenor of conversations on python-dev, it is very rare to encounter a problem that cannot be solved (and readably so) using the existing tools and constructs. -- Michael Chermside
Michael Chermside wrote:
# start of module initialized = False
def doSomething(): if not initialized: initialize()
But how do you do this if the thing in question is a class rather than a function? The module could export a function getSomeClass() that clients were required to use instead of just referencing the class, but that would be klunky in the extreme. 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. -- Greg Ewing, Computer Science Dept, +--------------------------------------+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | greg.ewing@canterbury.ac.nz +--------------------------------------+
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@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://boredomandlaziness.blogspot.com
Nick Coghlan wrote:
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).
Aren't all functions descriptors? py> def baz(): ... print "Evaluating baz!" ... return "Module attribute" ... py> baz() Evaluating baz! 'Module attribute' py> baz.__get__(__import__(__name__), None) <bound method ?.baz of <module '__main__' (built-in)>> py> baz.__get__(__import__(__name__), None)() Traceback (most recent call last): File "<interactive input>", line 1, in ? TypeError: baz() takes no arguments (1 given) How would your proposal change the invocation of module-level functions? STeVe -- You can wordify anything if you just verb it. --- Bucky Katt, Get Fuzzy
Steven Bethard wrote:
Nick Coghlan wrote:
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).
Aren't all functions descriptors?
So Josh pointed out.
py> def baz(): ... print "Evaluating baz!" ... return "Module attribute" ... py> baz() Evaluating baz! 'Module attribute' py> baz.__get__(__import__(__name__), None) <bound method ?.baz of <module '__main__' (built-in)>> py> baz.__get__(__import__(__name__), None)() Traceback (most recent call last): File "<interactive input>", line 1, in ? TypeError: baz() takes no arguments (1 given)
How would your proposal change the invocation of module-level functions?
It would, alas, break it. And now that I think about it, functions have to work the way they do, otherwise binding an arbitrary function to a class variable wouldn't work properly. So the class descriptor protocol can't be used as is at the module level, because functions are descriptor instances. Ah well, another idea runs aground on the harsh rocks of reality. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://boredomandlaziness.blogspot.com
On 10/17/05, Nick Coghlan <ncoghlan@gmail.com> wrote:
Ah well, another idea runs aground on the harsh rocks of reality.
I should point out that it's intentional that there are very few similarities between modules and classes. Many attempts have been made to unify the two, but these never work right, because the module can't decide whether it behaves like a class or like an instance. Also the direct access to global variables prevents you to put any kind of code in the get-attribute path. -- --Guido van Rossum (home page: http://www.python.org/~guido/)
participants (5)
-
Greg Ewing -
Guido van Rossum -
Michael Chermside -
Nick Coghlan -
Steven Bethard