[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