On Mon, Sep 7, 2015 at 10:19 PM, Steven D'Aprano
On Mon, Sep 07, 2015 at 06:23:13PM +1000, Chris Angelico wrote:
print("Hello, I am {b}. My favorite number is {a}.".format_map(locals()))
This one, though, is a bad idea for several reasons.
Such as what?
Using locals() for formatting is restricted - no globals, no expressions, and no nonlocals that aren't captured in some other way.
That's a feature, not a bug.
locals(), by definition, only includes locals. If you want globals, non-locals, built-ins, expressions, or the kitchen sink, you can't get them from locals(). Just because the locals() trick doesn't handle every possible scenario doesn't make it a bad idea for those cases it does handle, any more than it is a bad idea to use 2**5 just because the ** operator doesn't handle the 3-argument form of pow().
I probably wouldn't use the locals() form if the variable names were hard-coded like that, especially for just two of them:
"Hello, I am {b}. My favorite number is {a}.".format(a=a, b=b)
Where the locals() trick comes in handy is when your template string is not hard-coded:
if greet: template = "Hello, I am {name}, and my favourite %s is {%s}." else: template = "My favourite %s is {%s}." if condition: template = template % ("number", "x") else: template = template % ("colour", "c") print(template.format_map(locals())
It's still a poor equivalent for the others. In terms of "why do we have so many different ways to do the same thing", the response is "the good things to do with format_map(locals()) are not the things you can do with f-strings". If what you're looking for can be done with either, it's almost certainly not better to use locals(). ChrisA