I'm pulling in text strings with placeholders for instance attributes. I'm trying to write something that will get the place holder text, find the attribute with that name, and swap it in. I'm able to get the attribute, but to swap it in I'm having to hard code the placeholder.
The "new_text_string = ..." line gives me "KeyError: 'dntier'" The commented line below it works, but I don't want to have to hard code every possible attribute.
import re
class Test:
def __init__(self,mdtier,rxtier,dntier,vstier):
self.mdtier = mdtier,
self.rxtier = rxtier,
self.dntier = dntier,
self.vstier = vstier,
rec = Test('You Only','You Only','You + Family','You + Spouse')
text_string = 'Dental coverage for {dntier}.'
try:
text_variable = re.search('\{(.+?)\}', text_string).group(1)
except AttributeError:
text_variable = ''
if text_variable:
replacement = getattr(rec, text_variable)[0]
new_text_string = text_string.format(text_variable=replacement)
#new_text_string = text_string.format(dntier=replacement)
else:
new_text_string = text_string
The error you see is because this line
text_string.format(text_variable=replacement)
will replace a variable named text_variable
, but the string template is looking for a variable named dntier
. That is, the variable name is not evaluated, but passed literally.
Since you're trying to pass a keyword argument with a dynamic name, I suggest creating a dict and using **
:
new_text_string = text_string.format(**{text_variable: replacement})
Or, to simplify the code even further, you can use rec.__dict__
:
import re
class Test:
def __init__(self,mdtier,rxtier,dntier,vstier):
self.mdtier = mdtier,
self.rxtier = rxtier,
self.dntier = dntier,
self.vstier = vstier,
rec = Test('You Only','You Only','You + Family','You + Spouse')
text_string = 'Dental coverage for {dntier}.'
print(text_string.format(**rec.__dict__))