Here are a few options:
Format string (and Formatter class)
Using str.format
is the most pythonic way and pretty simple to read. Either style is popular:
Position arguments
'{0} some {0} words {0}'.format('house')
Named arguments
'{word} some {word} words {word}'.format(word='house')
In a comment you mentioned preserving the original format string because of other legacy code. You could hack around that like so:
'%s some %s words %s'.replace('%s', '{0}').format('house')
(I don't recommend it but you could "short circuit" this idea line by using 'house'
in the replace call instead of '{0}'
.)
That said, I really think changing the template string in the first place is a better idea.
Template strings
One more alternative comes to mind after glancing at the string
docs: the older string.Template
class. By default it substitutes $
-based values, but you can subclass it overriding the delimiter character. For example:
class MyTemplate(Template):
"""
Overriding default to maintain compatibility with legacy code.
"""
delimiter = '%'
t = MyTemplate('%s some %s words %s')
t.substitute(s='house')
Remember this is less common but you could write it once and re-use it every time you work with a string like this (assuming there's only one input value being substituted in). Writing it once is Pythonic at least!
Literal string interpolation
In Python 3.6, Ruby-style string interpolation is another option that the community hasn't come to a consensus on yet. For example:
s = 'house'
f'{s} some {s} words {s}'