Python Forum
trying to learn f-strings - puzzled by format() protocol
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
trying to learn f-strings - puzzled by format() protocol
#1
the language reference section describing Formatted string literals says: "The result is then formatted using the format() protocol. The format specifier is passed to the __format__() method of the expression or conversion result." it is very unclear what is going on here. it seems like it is saying that it is formated twice (passing the result on to be formatted again). but the 2nd formatting makes no sense, if the result (presumably a string) is passed to __format__(). what normally happens there?

the examples look simple and make sense. but not understanding the described steps means i'm not going to know the subtle behavior with something strange, or weird bugs.

an online article says: "The expressions are evaluated at runtime and then formatted using the __format__ protocol. As always, the Python docs are your friend when you want to learn more." it has nice looking examples that don't give a solid understanding. it can't be my friend until i understand it.

i've already seen some heavy-duty use of f-strings that just didn't make sense, to me. at least, it didn't, yet. this is why i want a solid understanding of what is going on. there seems to be a more advanced level of understanding needed to be able to interpret all kings of f-string.

does anyone understand what i am not understanding? i know enough to make some working f-strings. but it seems my understanding has some serious gaps.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#2
I don't think it saying its formatted twice, the f string is passed to format() to do the actual formatting.
Reply
#3
(Jul-25-2019, 05:29 AM)Skaperen Wrote: there seems to be a more advanced level of understanding needed to be able to interpret all kings of f-string.
You dont really need to know the inner workings of format to use f-string over format. F-strings are suppose to be more easily understandable as well as less code to type.
Recommended Tutorials:
Reply
#4
It's formatted one time. Here the proof of it:

# explaining with code
class MyFormat(str):
    def __format__(self, fmt_str):
        print('Magic method __format__ was called.')
        fmt_str = fmt_str.strip()
        if 'UPPER' == fmt_str:
            return self.upper()
        elif 'LOWER' == fmt_str:
            return self.lower()
        else:
            return self




my_str = MyFormat('Hello World')

# 3 calls, 3 times formatting
print(f'{my_str: UPPER }')
print(f'{my_str: LOWER }')
print(f'{my_str}')


# the same with the format method
# 3 calls, 3 times formatting
print('{:UPPER}'.format(my_str))
print('{:LOWER }'.format(my_str))
print('{}'.format(my_str))
Output:
Magic method __format__ was called. HELLO WORLD Magic method __format__ was called. hello world Magic method __format__ was called. Hello World Magic method __format__ was called. HELLO WORLD Magic method __format__ was called. hello world Magic method __format__ was called. Hello World
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#5
(Jul-25-2019, 11:37 AM)metulburr Wrote:
(Jul-25-2019, 05:29 AM)Skaperen Wrote: there seems to be a more advanced level of understanding needed to be able to interpret all kings of f-string.
You dont really need to know the inner workings of format to use f-string over format. F-strings are suppose to be more easily understandable as well as less code to type.

i need to, at least, understand what the documentation is trying to say. it describes some formatting, then it says the result is passed to __format__(). is it just the string result that is being passed? what would __format__() do with it, like that?

(Jul-25-2019, 12:28 PM)DeaD_EyE Wrote: It's formatted one time. Here the proof of it:

# explaining with code
class MyFormat(str):
    def __format__(self, fmt_str):
        print('Magic method __format__ was called.')
        fmt_str = fmt_str.strip()
        if 'UPPER' == fmt_str:
            return self.upper()
        elif 'LOWER' == fmt_str:
            return self.lower()
        else:
            return self




my_str = MyFormat('Hello World')

# 3 calls, 3 times formatting
print(f'{my_str: UPPER }')
print(f'{my_str: LOWER }')
print(f'{my_str}')


# the same with the format method
# 3 calls, 3 times formatting
print('{:UPPER}'.format(my_str))
print('{:LOWER }'.format(my_str))
print('{}'.format(my_str))
Output:
Magic method __format__ was called. HELLO WORLD Magic method __format__ was called. hello world Magic method __format__ was called. Hello World Magic method __format__ was called. HELLO WORLD Magic method __format__ was called. hello world Magic method __format__ was called. Hello World

as described in the documentation, calling __format__() with the result would be the 2nd step.

from your example, it is calling there, so i need to understand how that works (but i will read over your code a few times to see if i can pick up on it).

(Jul-25-2019, 05:41 AM)Yoriz Wrote: I don't think it saying its formatted twice, the f string is passed to format() to do the actual formatting.

the documentation describes two steps, the 2nd being the call to __format__(). maybe they worded it badly?
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#6
in the documentation i see it say "An empty string is passed when the format specifier is omitted." is "format specifier" the "format_spec" that follows ":" (as in the next paragraph)? i don't see any format_specs in DeaD_EyE's code. but his print does not show arguments so i can't tell if __format__ was really called with an empty string.

in the syntax chart, the 2nd to last line has "format_spec ::= (literal_char| NULL |replacement_field)*". what does the * mean? that it can be repeated 0 or more times as in regular expressions?

this is in the PDF language reference for 3.7.4 (though i am running 3.6.8).
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#7
The format specs are defined in the types str, int, float, datetime (or somewhere else), etc..
If you do your own format, you must write a parser for it.
The data is processed in the __format__ method and the __format__ method must return always a string.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#8
it does not appear that enough information can be passed to __format__() for it to do the correct formatting ... unless i misunderstand something.

i am starting to use f-strings for simple cases (strings and numbers). it is more convenient.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  print a list strings is fast but printing the joined strings is slow Skaperen 9 3,827 Aug-26-2019, 07:48 PM
Last Post: Skaperen

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020