pythonglobal-variableslocal-variables

Python: cache a local function variable for subsequent calls


In C/C++, a function can declare a local variable as static. When doing so, the value remains in memory and is available to subsequent calls to the function (this variable is no longer local, but that's besides the point).

Is there a way to do something similar in Python, without having to declare any global variable outside of the function?

Use case: a function that (among other things) uses a regex to extract a value from an input string. I want to pre-compile the pattern (re.compile()), without having to declare the variable outside of the function scope.

I can inject a variable directly into globals():

globals()['my_pattern'] = re.compile(...)

But it doesn't look like a good idea.


Solution

  • You could use a function attribute. In Python, functions are first-class objects, so you can abuse of this feature to simulate a static variable:

    import re
    
    def find_some_pattern(b):
        if getattr(find_some_pattern, 'a', None) is None:
            find_some_pattern.a = re.compile(r'^[A-Z]+\_(\d{1,2})$')
        m = find_some_pattern.a.match(b)
        if m is not None:
            return m.groups()[0]
        return 'NO MATCH'
    

    Now, you can try it:

    try:
        print(find_some_pattern.a)
    except AttributeError:
        print('No attribute a yet!')
    
    for s in ('AAAA_1', 'aaa_1', 'BBBB_3', 'BB_333'):
        print(find_some_pattern(s))
    
    print(find_some_pattern.a)
    

    This is the output:

    No attribute a yet!
    initialize a!
    1
    NO MATCH
    3
    NO MATCH
    re.compile('^[A-Z]+\\_(\\d{1,2})$')
    

    It is not the best approach (wrappers or callables are way more elegant, and I suggest you use one of them), but I thought this clearly explains the meaning of:

    In Python, functions are first-class objects.