Partial string formatting?
Jeff Epler
jepler at unpythonic.net
Tue Jan 21 17:41:39 EST 2003
I'd like to mention one more potential problem with this "partial
formatting" idea. It seems that you wish to take a string through
multiple formatting steps. But what about the following format string?
"%(item)s is %(frac)d%% as hard as glass."
after the first formatting step, it might look like this:
"%(item)s is 37% as hard as glass."
but when you format again, you'll get an error, because "% " is not a
proper format specifier.
You can run into a variation of this problem if the formatted thing
contains a %. For instance:
"The symbol '%(sym)s' is spelled out as '%(word)s'."
becoming
"The symbol '%' is spelled out as '%(word)s'."
I think this question must be addressed if your goal is truly to do
incremental formatting. For instance, you might use a wrapper class (or
string subclass) so that the % operator updates an internal dict, and the
__str__ method returns the string formatted with the current internal dict:
(Note that my earlier 'format' function doesn't work in the presence of
'%%', either. The __str__ method of IncrementallyFormattedString seems to,
though. It still won't properly handle other weird stuff, such as the
legal-but-unlikely '%(%)s')
Jeff
class IncrementallyFormattedString:
def __init__(self, s, d={}):
self.s = s
self.d = d.copy()
def __str__(self):
s = self.s
d = self.d
i = s.find("%")
out = [s[:i]]
while 1:
if s[i:i+2] == "%%":
out.append("%")
i=i+2
continue
j = s.find("%", i+1)
if j == -1:
try:
out.append(s[i:] % d)
except KeyError:
out.append(s[i:])
break
#print "__str__", i, j, s[i:j]
try:
out.append(s[i:j] % d)
except KeyError:
out.append(s[i:j])
i = j
return "".join(out)
def __mod__(self, d):
d = d.copy()
d.update(self.d)
return IncrementallyFormattedString(self.s, d)
I = IncrementallyFormattedString
s = I("%(item)s is %(frac)d%% as hard as glass.")
s = s % {'frac': 37}
print s
s = s % {'item': 'Spam'}
print s
s = I("The symbol '%(sym)s' is spelled out as '%(word)s'.")
s = s % {'sym': '%'}
print s
s = s % {'word': 'percent'}
print s
More information about the Python-list
mailing list