[Python-ideas] Python hook just before NameError
Steven D'Aprano
steve at pearwood.info
Mon Dec 29 15:12:08 CET 2014
On Tue, Dec 30, 2014 at 12:02:32AM +1100, Chris Angelico wrote:
> On Mon, Dec 29, 2014 at 11:46 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:
> > However, even today, it's not particularly difficult to create custom launch
> > scripts that initialise __main__ with a few different modules based on what
> > you plan to work on and then set os.environ["PYTHONINSPECT"] = "1" to drop
> > into the interactive interpreter:
> >
> > $ python3 -c "import sys, os; os.environ['PYTHONINSPECT'] = '1'"
> >>>> sys, os
> > (<module 'sys' (built-in)>, <module 'os' from '/usr/lib64/python3.4/os.py'>)
> >>>>
>
> Once again, that's fine for sys and os, which won't take long to
> import. For this to work with _every_ module on the system, you'd need
> to couple it with a lazy import mechanism. We had some proposals along
> those lines recently... what happened to them?
I just threw this lazy import proxy object together. I haven't tested it
extensively, but it seems to work:
from types import ModuleType
class LazyImporter(ModuleType):
def __init__(self, name):
self._module = None
self.__name__ = name
self.__package__ = None
def __getattr__(self, name):
if self._module is None:
module = self._module = __import__(self.__name__)
self.__package__ = module.__package__
else:
module = self._module
return getattr(module, name)
def lazy_import(name):
from sys import modules
if name in modules:
return modules[name]
else:
return LazyImporter(name)
Usage:
decimal = lazy_import('decimal')
decimal.Decimal
If the module has already been cached, you get the module itself,
otherwise you get a proxy.
This was so obvious and simple, I cannot believe I am the first to have
thought of it. Perhaps there is something similar that has been
extensively used and tested in the real-world that the standard library
could steal?
--
Steven
More information about the Python-ideas
mailing list