I have been using this function for some time now, which casts the Dict
of inputted keyword arguments as a SafeDict
object that subclasses Dict
.
def safeformat(str, **kwargs):
class SafeDict(dict):
def __missing__(self, key):
return '{' + key + '}'
replacements = SafeDict(**kwargs)
return str.format_map(replacements)
I didn't make this up, but I think it's a good solution. The one downside is that you can't call mystring.safeformat(**kwargs)
- of course, you have to call safeformat(mystring,**kwargs)
.
If you're really interested in being able to call mystr.safeformat(**kwargs)
(which I am interested in doing!), consider using this:
class safestr(str):
def safeformat(self, **kwargs):
class SafeDict(dict):
def __missing__(self, key):
return '{' + key + '}'
replacements = SafeDict(**kwargs)
return safestr(self.format_map(replacements))
You can then create a safestr
object as a = safestr(mystr)
(for some str
called mystr
), and you can in fact call
mystr.safeformat(**kwargs)
.
e.g.
mysafestr = safestr('Hey, {friendname}. I am {myname}.')
print(mysafestr.safeformat(friendname='Bill'))
prints
Hey, Bill. I am {myname}.
This is cool in some ways - you can pass around a partially-formatted safestr
, and could call safeformat
in different contexts. I especially like to call mystr.format(**locals())
to format with the appropriate namespace variables; the safeformat
method is especially useful in this case, because I don't always carefully looks through my namespace.
The main issue with this is that inherited methods from str
return a str
object, not a safestr
. So mysafestr.lower().safeformat(**kwargs)
fails. Of course you could cast as a safestr
when using safeformat
:
safestr(mysafestr.lower()).safeformat(**kwargs)
,
but that's less than ideal looking. I wish Python just gave the str
class a safeformat
method of some kind.