3 ms·
But couldn't that inefficiency be optimized away in the implementation? (Load imports lazily).
by smitherfield 9y ago
But couldn't that inefficiency be optimized away in the implementation? (Load imports lazily).
- marmaduke 9y agoIt can't be done automatically because imported can execute code. Since that's part of the semantics, you have to be lazy by hand.
- deckiedan 9y agoOnly on the first load ever. When modules are compiled to their byte code, they could get a "clean" flag if they don't execute code, which means they get loaded lazily next time.
- marmaduke 9y agoOk but figuring out what executes code might require executing code: consider non trivial use of meta classes, where an inconspicuous subclass actually invokes e.g. A registration process like a Django model class.
- smitherfield 9y agoSure, but, just spitballing here, could a substantial fraction of imported code benefit even with a very conservative heuristic? In any case, given your points, it seems like a future Python version ought to introduce a new version of the import statement with lazy semantics (which, besides eliminating dead code, is also IMO the more correct/explicit behavior when importing symbols).
- deckiedan 9y agoThat's kind of what I was hoping. I suspect a vast proportion of normal Python code doesn't use the meta programming and run on import and so on.
- joshuamorton 9y agoIf a module imports anything, it cannot be assumed clean, since any of its imports may execute code, and they will not be available at compile time.
- marmaduke 9y agoIt'd be pretty easy to do the experiment, since you can override the import logic and do lazy imports, eg. class LazyModule: def __init__(self, name): self.name = name def __getattr__(self, key): mod = {} exec('import %s as mod', mod) self.mod = mod['mod'] return getattr(self.mod, key) class LazyImporter: def get_module(self, name): return LazyModule(name)