Python formatted string literals
We have discussed Python string literals with different prefixes in another post, here we will see the Python formatted string literals.
Link : Python string literals
A formatted string literal is defined as string literals having the prefix ‘f‘ or ‘F‘. Any string literal that has the prefix ‘f’ or ‘F’ is undoubtedly a formatted string literal.
Making any string literal to formatted type is as easy as prefixing the string literal with the ‘f’ or ‘F’. We can also use the prefixes “fr”, “Fr”, “fR”, “FR”, “rf”, “rF”, “Rf” and “RF” to apply the formatted string literals rule to any of the string. But what is so unique about these prefixes that make formatted string literals so unique in properties and behaviour.
In formatted string literals we are allowed to replace a certain part of the string with whatever value we desire. This part which can be replaced with any value is known as replacement fields. Replacement fields are usually surrounded by braces ({}) and have the name of an object which you want to replace its value with.
Consider the code below.
>>> name='John' >>> fs=f'My name is {name}' >>> fs 'My name is John'
In the above code, the field {name} is replaced with the value of the name string, which is ‘John’.
More example provided below.
>>> place="Mariana Trench" >>> species='Megalodon' >>> movie='The Meg' >>> st=F"In the '{movie}' movie, {species} is found in the {place}." >>> st "In the 'The Meg' movie, Megalodon is found in the Mariana Trench." >>> #Replacing with list value >>> ks=[12 ,89 , 'txt'] >>> sr=f'new name {ks}' >>> sr "new name [12, 89, 'txt']" >>> #replacing with dictionary >>> dic={23:'23' , 45:'45' , 56:'56'} >>> s=f'A dictionary example: {dic}' >>> s "A dictionary example: {23: '23', 45: '45', 56: '56'}"
The ‘The Meg’ movie wasn’t great though.
Note since formatted string literals have replacement fields their exact value are determined only during the run-time.
Specifying a conversion
While using formatted string literals we can specify the conversion rule of the expression that will replace the replacement fields. This can be done using the conversion ‘!s‘, ‘!r‘ and ‘!a‘. To use the conversion we will add them just after the object name inside the braces. What each of the conversion stands for is discussed below.
‘!s’ conversion
The ‘!s’ conversion will call the function str(). This means the function str() will determine what value to replace the replacement field. In other words, when the object present in the replacement field is passed as an argument to str(), whatever is returned by str() will replace the replacement field.
Please read the str() function first if you are confused.
Link : Python str()
Consider the code example below.
>>> ls=[34 , 89 , 'list'] >>> #check returned value of str when 'ls' is an argument >>> str(ls) "[34, 89, 'list']" >>> fs1=F'list returned as tring by str() : {ls!s}' >>> fs1 "list returned as tring by str() : [34, 89, 'list']"
Whatever is returned by str(ls) will also replaced the {ls!s} field. So to know what will replace the replacement field when using ‘!s’ conversion, simpley pass the object inside the field to str() and the returned value is the replacement of the field, easy isn’t?
If you know what is class and have read the link on str() function given above, try using a class object inside the replacement field with the ‘!s’ conversion, your understanding of the conversion will become much clearer.
One example is provided below. If you do not know what is class then learn the basic of a class first and then continue.
>>> class New: def __init__(nw , st): nw.st=st def __str__(self): return '!s conversion field' >>> n=New('heap') >>> str(n) '!s conversion field' >>> s=f"true {n!s}" >>> s 'true !s conversion field'
str(n) returns ‘!s conversion field‘, so {n!s} is replaced by ‘!s conversion field‘ inside the ‘s’ string.
‘!r’ conversion
The ‘!r’ conversion will call the repr() function. The concept here is similar to the ‘!s’ conversion except in this case whatever is returned by repr() function will replaced the replacement field.
Please know what repr() function does to undertand fully the conversion.
Link : Python repr()
A code example is given below. Look at the returned value of the repr() function when the object inside the replacement field is passed as an argument and then compare it with the output of the formatted string.
>>> dic={23:'23' , 56:'56' , 1000:'1000'} >>> repr(dic) "{23: '23', 56: '56', 1000: '1000'}" >>> fs=F'Dictionary : {dic!r}' >>> fs "Dictionary : {23: '23', 56: '56', 1000: '1000'}"
The retuned value of repr(dic) does match with the replaced value in the replacement field of fs string.
Another example is given below and it is based on class so read it only if you know what class is.
>>> class Mark: def __init__(mr , s): mr.s=s >>> mk=Mark(345) >>> repr(mk) '<__main__.Mark object at 0x0367B9D0>' >>> fr=f"Mark class info: {mk!r}" >>> fr 'Mark class info: <__main__.Mark object at 0x0367B9D0>'
The string returned by repr(mk) has replaced the replacement field in fr string.
‘!a’ conversion
The ‘!a’ conversion calls the ascii() function. Like the two conversions discussed above the same rules apply to ‘!a’ conversion. Whatever is returned by ascii() with the object inside the replacement filed as the argument passed, will replace the replacement field in the formatted string literal.
Link : Python ascii()
>>> st={23 ,89 ,'token'} >>> ascii(st) "{89, 'token', 23}" >>> fs=F'Set example: {st!a}' >>> fs "Set example: {89, 'token', 23}"
Well the example is simple so nothing much to say here.
Consider another example. In this example, let us use a Unicode string object inside the replacement field.
>>> chinese='汉字指事字' >>> ascii(chinese) "'\\u6c49\\u5b57\\u6307\\u4e8b\\u5b57'" >>> #note the returned value >>> fs=F'Chinese alphabets returned by ascii(): {chinese!a}' >>> fs "Chinese alphabets returned by ascii(): '\\u6c49\\u5b57\\u6307\\u4e8b\\u5b57'"
As we know, ascii() returns a Unicode character as hexadecimal number with the escape sequence ‘\u’ and that is exactly what has replaced the replacement field in the formatted string literal in the above code.
Read about escape sequence here : Python escape sequence