The %s operator is put where the string is to be specified. The number of values you want to append to a string should be equivalent to the number specified in parentheses after the % operator at the end of the string value. The following Python code illustrates the way of performing string formatting.
String formatting is the process of infusing things in the string dynamically and presenting the string. There are four different ways to perform string formatting:- Formatting with % Operator. Formatting with format() string method. Formatting with string literals, called f-strings.
As expected, the floating point number (1.9876) was rounded up to two decimal places – 1.99. So %. 2f means to round up to two decimal places. You can play around with the code to see what happens as you change the number in the formatter.
If you know in what order you're formatting things:
s = '{foo} {{bar}}'
Use it like this:
ss = s.format(foo='FOO')
print ss
>>> 'FOO {bar}'
print ss.format(bar='BAR')
>>> 'FOO BAR'
You can't specify foo
and bar
at the same time - you have to do it sequentially.
You could use the partial
function from functools
which is short, most readable and also describes the coder's intention:
from functools import partial
s = partial("{foo} {bar}".format, foo="FOO")
print s(bar="BAR")
# FOO BAR
You can trick it into partial formatting by overwriting the mapping:
import string
class FormatDict(dict):
def __missing__(self, key):
return "{" + key + "}"
s = '{foo} {bar}'
formatter = string.Formatter()
mapping = FormatDict(foo='FOO')
print(formatter.vformat(s, (), mapping))
printing
FOO {bar}
Of course this basic implementation only works correctly for basic cases.
This limitation of .format()
- the inability to do partial substitutions - has been bugging me.
After evaluating writing a custom Formatter
class as described in many answers here and even considering using third-party packages such as lazy_format, I discovered a much simpler inbuilt solution: Template strings
It provides similar functionality but also provides partial substitution thorough safe_substitute()
method. The template strings need to have a $
prefix (which feels a bit weird - but the overall solution I think is better).
import string
template = string.Template('${x} ${y}')
try:
template.substitute({'x':1}) # raises KeyError
except KeyError:
pass
# but the following raises no error
partial_str = template.safe_substitute({'x':1}) # no error
# partial_str now contains a string with partial substitution
partial_template = string.Template(partial_str)
substituted_str = partial_template.safe_substitute({'y':2}) # no error
print substituted_str # prints '12'
Formed a convenience wrapper based on this:
class StringTemplate(object):
def __init__(self, template):
self.template = string.Template(template)
self.partial_substituted_str = None
def __repr__(self):
return self.template.safe_substitute()
def format(self, *args, **kws):
self.partial_substituted_str = self.template.safe_substitute(*args, **kws)
self.template = string.Template(self.partial_substituted_str)
return self.__repr__()
>>> s = StringTemplate('${x}${y}')
>>> s
'${x}${y}'
>>> s.format(x=1)
'1${y}'
>>> s.format({'y':2})
'12'
>>> print s
12
Similarly a wrapper based on Sven's answer which uses the default string formatting:
class StringTemplate(object):
class FormatDict(dict):
def __missing__(self, key):
return "{" + key + "}"
def __init__(self, template):
self.substituted_str = template
self.formatter = string.Formatter()
def __repr__(self):
return self.substituted_str
def format(self, *args, **kwargs):
mapping = StringTemplate.FormatDict(*args, **kwargs)
self.substituted_str = self.formatter.vformat(self.substituted_str, (), mapping)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With