[Python-ideas] rebooting the lazy regex discussion as something stricty more narrow for lazy expensively computed globals

Ronny Pfannschmidt Ronny.Pfannschmidt at gmx.de
Mon Mar 25 20:30:52 CET 2013


Hi,

since the previous discussions raised lots of bikeshedding in 
maintenance-pain directions about pick/marshal in sourcecode,

i'd like to reboot the discussion in a more narrow scope

the pattern is that the stdlib has lazy-computed private globals in 
various modules

i would like to propose an alternative way of doing those

instead of code such as


_hostprog = None
def splithost(url):
     """splithost('//host[:port]/path') --> 'host[:port]', '/path'."""
     global _hostprog
     if _hostprog is None:
         import re
         _hostprog = re.compile('^//([^/?]*)(.*)$')
     ...

i would prefer to see code like
from functools import lazy_global

@lazy_global
def _hostprog():
     return re.compile('^//([^/?]*)(.*)$')


as far as i can tell the implementation for simple cases of expensive 
things will not need smart proxying, just some getattr hook

an untested example implementation could thus look like the following
(note that it would end up creating the object twice in thread races a 
lock may be necessary)

class LazyGlobal(object)
     def __init__(self, func):
        self.__func = func

     def __getattr__(self, name):
        try:
            obj = self.__computed
        except AttributeError:
            self.__computed = obj = self.__func()
        	   # replace myself in the module scope to get rid of indirection
            # in the except block cause if someone imports us we need to 
stay here
            self.__func.__globals__[self.__func.__name__] = obj
        return getattr(obj, name)


	





More information about the Python-ideas mailing list