I'm trying to quote one of the values I send to an f-string in Python:
f'This is the value I want quoted: \'{value}\''
This works, but I wonder if there's a formatting option that does this for me, similar to how %q
works in Go. Basically, I'm looking for something like this:
f'This is the value I want quoted: {value:q}'
>>> This is the value I want quoted: 'value'
I would also be okay with double-quotes. Is this possible?
Use the explicit conversion flag !r
:
>>> value = 'foo'
>>> f'This is the value I want quoted: {value!r}'
"This is the value I want quoted: 'foo'"
The r
stands for repr
; the result of f'{value!r}'
should be equivalent to using f'{repr(value)}'
. Conversion flags are a feature carried over from str.format
, which predates f-strings.
For some reason undocumented in PEP 3101, but mentioned in the docs, there's also an !a
flag which converts with ascii
:
>>> f'quote {"π₯"!a}'
"quote '\\U0001f525'"
And there's an !s
for str
, which seems useless... unless you know that objects can override their formatter to do something different than object.__format__
does. It provides a way to opt-out of those shenanigans and use __str__
anyway.
>>> class What:
... def __format__(self, spec):
... if spec == "fancy":
... return "π
πππΆππ"
... return "potato"
... def __str__(self):
... return "spam"
... def __repr__(self):
... return "<wacky object at 0xcafef00d>"
...
>>> obj = What()
>>> f'{obj}'
'potato'
>>> f'{obj:fancy}'
'π
πππΆππ'
>>> f'{obj!s}'
'spam'
>>> f'{obj!r}'
'<wacky object at 0xcafef00d>'
One example of where that !s
might be useful in practice is with alignment/padding of types that don't otherwise support it:
>>> f"{[1,2]:.>10}"
TypeError: unsupported format string passed to list.__format__
>>> f"{[1,2]!s:.>10}"
'....[1, 2]'
Or types which "support" it, but not how you may have intended:
>>> from datetime import date
>>> f"{date.today():_^14}"
'_^14'
>>> f"{date.today()!s:_^14}"
'__2024-03-25__'