Yes, it sucks that Python does not have that. I miss a let statement ...
let myvar:
...
... which creates a scope. Or just ...
let:
...
... in case we do not need to return anything from the scope.
Okay, theories aside, until the day Python does hopefully nicer, I do it the following way:
def _let(): # type: ignore
pattern = re.compile(r'(foo)')
def handler(match):
return 'bar' if match.group(1) == 'foo'
def only_bars(string):
return pattern.sub(handler, string)
return only_bars
only_bars = _let()
# pattern and handler do not exist here
Basically for what IIFE's in JavaScript ((function(){...})();) were used, until they introduced let and const which are aware of scoping using curly brackets.
The underscore in _let prevents that this name gets exported, and the # type: ignore silences the type checker when defining multiple _let's.