[Python-ideas] re.compile_lazy - on first use compiled regexes

Nick Coghlan ncoghlan at gmail.com
Sat Mar 23 17:08:38 CET 2013


On Sat, Mar 23, 2013 at 8:33 AM, Antoine Pitrou <solipsis at pitrou.net> wrote:
> On Sat, 23 Mar 2013 16:30:39 +0100
> Masklinn <masklinn at masklinn.net> wrote:
>>
>> Right, but in this case while I called it a cache the semantics really
>> is a lazy singleton: only create the regex object when it's needed, but
>> keep it around once it's been created.
>
> Perhaps we need a functools.lazy_compute() function:
>
>   pat = functools.lazy_compute(re.compile, r"my very long regex")

As in something like:

    def compute_once(f, *args, **kwds):
        value = not_called = object()
        @wraps(f):
        def compute_on_demand():
            nonlocal value
            if value is not_called:
                value = f(*args, **kwds)
            return value
        return compute_on_demand

    _pattern = compute_once(re.compile, r"my very long regex")

    def use_pattern(data):
        return _pattern().search(data)

Runtime overhead is then just the identity check for the initial sentinel value.

The difference with both functools.partial and functools.lru_cache is
that it wouldn't support customisation at call time - you have to
fully define the operation up front, the only thing you're deferring
is the actual call. That call will only happen once, with all
subsequent calls returning the same value as the initial call. This is
what allows the call time overhead to be stripped back to almost
nothing.

Seems like a reasonable justification for a dedicated tool to me.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia



More information about the Python-ideas mailing list