Interpolate variables and expressions in strings the ruby way. This is similar in functionality to recipe 496885, though implemented differently and with a different interpolation syntax.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import sys, re
def interp(string):
locals = sys._getframe(1).f_locals
globals = sys._getframe(1).f_globals
for item in re.findall(r'#\{([^}]*)\}', string):
string = string.replace('#{%s}' % item,
str(eval(item, globals, locals)))
return string
test1 = 'example'
def tryit():
test2 = 1
# variable interpolation
print interp('This is an #{test1} (and another #{test1}) and an int (#{test2})')
# expression interpolation
print interp('This is an #{test1 + " (and another " + test1 + ")"} and an int (#{test2})')
tryit()
|
Ruby uses an inline string interpolation syntax using #{} (which combines perl's ${} and $() into one). It interpolates expressions as well as variables. This recipe emulates that functionality in python. Other recipies offer similar functionality (335308, 496885), though either without expression interpolation, or with an interpolation syntax which I find to be esoteric and hard to use.
Caveat: As with recipe 496885, this recipe is insecure in contexts where arbitrary input is possible, as it uses eval for evaluation of expressions; so don't use it in untrusted contexts.
What about instance variables? Is there a straighforward way to extend this recipe to allow for instance variables as well as locals and globals? This would be useful in order to allow the use of these templates in a __str__ or similar function that might access instance vars.
I don't understand... Hmmm...not sure I get what you're asking...this works fine for me...
What am I missing?