I find myself writing code like this relatively often:
_munge_text_re = re.compile("... complicated regex ...")
def munge_text(text):
match = _munge_text_re.match(text)
... do stuff with match ...
Only munge_text uses _munge_text_re, so it would be better to make it local to the function somehow, but if I move the re.compile line inside the def then it will be evaluated every time the function is called, defeating the purpose of compiling the regular expression.
Is there a way to make _munge_text_re local to munge_text while still evaluating its initializer only once? The single evaluation needn't happen at module load time; on the first invocation of munge_text would be good enough.
The example uses a regex, and the majority of the time I need this it's for a regex, but it could be any piece of data that's expensive to instantiate (so you don't wanna do it every time the function is called) and fixed for the lifetime of the program. ConfigParser instances also come to mind.
Extra credit: For reasons too tedious to get into here, my current project requires extreme backward compatibility, so a solution that works in Python 2.0 would be better than one that doesn't.
Now that it has state, just make a class for it:
class TextMunger(object):
def __init__(self, regex):
self._pattern = regex
self._munge_text_re = None
def __call__(self, text):
if self._munge_text_re is None:
self._munge_text_re = re.compile(self._pattern)
match = self._munge_text_re.match(text)
# ... do stuff with match ...
munge_text = TextMunger("... complicated regex ...")
# The rest of your code stays the same
In case you didn't know, the __call__ method on a class means that objects can be called as though they were functions, so you can continue to use munge_text(text) just as you did before.
(This kind of problem is actually what led to my question about a lazy property decorator in Python, which might also interest you; I wouldn't bother with that unless you find yourself repeating this pattern a lot though.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With