[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