I am using a re.sub callback to replace substrings with random values, but I would like the random values to be the same across different strings. Since the re.sub callback does
You could use a function object.
class A(object):
def __init__(self, mappings):
self.mappings = mappings
def __call__(self, match):
return str(eval(match.group(0)[2:-1], self.mappings))
evaluate = A({'A': 1, 'B': 2})
You could create a closure.
def evaluator(mappings):
def f(match):
return str(eval(match.group(0)[2:-1], mappings))
return f
evaluate = evaluator({'A': 1, 'B': 2})
Since f
is just a single statement, you could simply use lambda
:
def evaluator(mappings):
return lambda match: str(eval(match.group(0)[2:-1], mappings))
The variant I would recommend:
mappings = {'A': 1, 'B': 2} # Or whatever ...
def evaluate(match):
return str(eval(match.group(0)[2:-1], mappings))
newstring = sub(r'\#\{([^#]+)\}', evaluate, string)
i.e. simply put the def evaluate(..)
just before the sub()
, as a local function.
The easiest way I guess is to make use of functools.partial
, which allows you create a "partially evaluated" function:
from functools import partial
def evaluate(match, mappings):
return str(eval(match.group(0)[2:-1], mappings))
mappings = {'A': 1, 'B': 2} # Or whatever ...
newstring = sub(r'\#\{([^#]+)\}', partial(evaluate, mappings=mappings), string)