It seems that one solution is to use lambdas, which are explored below.
What other solutions are there?
Imagine that one wants to format a string selecting the format from several f-strings. Unfortunately, the obvious straightforward way of having the f-strings as values in a dictionary, does not work as desired, because the f-strings are evaluated when creating the dictionary. This unhappy way follows.
year, month, day = 'hello', -1, 0
date_formats = {
'iso': f'{year}-{month:02d}-{day:02d}',
'us': f'{month}/{day}/{year}',
'other': f'{day} {month} {year}',
}
Notice below that the current values of year, month, and day are ignored when evaluating date_formats['iso'].
year, month, day = 2017, 3, 27
print(year, month, day)
print(date_formats['iso'])
2017 3 27 hello--1-0
A solution is to use lambdas in the dictionary, and call them later, as shown below.
year, month, day = 'hello', -1, 0
# year, month, and day do not have to be defined when creating dictionary.
del year # Test that with one of them.
date_formats = {
'iso': (lambda: f'{year}-{month:02d}-{day:02d}'),
'us': (lambda: f'{month}/{day}/{year}'),
'other': (lambda: f'{day}.{month}.{year}'),
}
dates = (
(2017, 3, 27),
(2017, 4, 24),
(2017, 5, 22),
)
for format_name, format in date_formats.items():
print(f'{format_name}:')
for year, month, day in dates:
print(format())
iso: 2017-03-27 2017-04-24 2017-05-22 us: 3/27/2017 4/24/2017 5/22/2017 other: 27.3.2017 24.4.2017 22.5.2017
This also answers the question about what good use there is for Zak K (aka y2kbugger)'s crazy whacko f-string lambdas. Thanks Zak!