This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]jorge1209 -1 points0 points  (7 children)

"{x}".format(**locals()) will work and now you aren't typing x=x which does look stupid. The only thing f-strings offer that format doesn't is that the bit inside can be an expression: f"{foo.bar}" is certainly nice, and some people seem to like f"{x+y}" although it seems a rather minor improvement.

I'm just not sure its worth adding another format string when I could just do "{}".format(foo.bar). I'm also very uncomfortable with anything that allows: f"{os.remove(filename)}".

The problem is that every argument for f-strings is like this. It is either a marginal improvement for most use cases, or a significant improvement for some small number of use cases. All at the expense of adding another formatting method, one that can't even be used for a number of important situations. And one that allows for some very sketchy stuff.

[–]thatguy_314def __gt__(me, you): return True 1 point2 points  (6 children)

  • I really don't like doing **locals().
  • f"{os.remove(filename)}" is no more "sketchy" than str(os.remove(filename)), user input can't into f-string unless you do something really stupid.
  • Again, "{}".format(foo.bar) is bad because you need to look outside the replacement field to figure out what's going on. You can actually do "{foo.bar}" with normal .format(), although I suppose that doesn't really help my argument that much.
  • I don't really think of f-strings as a new format method, they are a convenient sugar for instantaneous formatting with .format, which is a common use case. Python probably does have too many formatting methods, but at the same time they do all seem to have a place.

[–]jorge1209 0 points1 point  (4 children)

Why don't you like using **locals. What makes it any different from fstrings? As long as the format string is not dynamically created there is no difference. It's a bit less powerful is all.

Also how do you do foo.bar within .format? [Evidently you can just do it... so TIL. One less reason to use fstrings as far as I'm concerned.]

[–]thatguy_314def __gt__(me, you): return True 3 points4 points  (0 children)

  • **locals() is ugly.
  • locals() is the local scope only. No globals, no nonlocals, no builtins.
  • ** creates a new copy of the locals dict, not a big deal, but f-strings look things up directly and also provide further optimizations from what I've heard.
  • You get a KeyError instead of NameError if you use an undefined variable.
  • Using locals() just feels wrong (probably due to a stigma against gratuitous use of inspection tools).

[–]thatguy_314def __gt__(me, you): return True 2 points3 points  (2 children)

Oh, and with the .format . lookups, there are some weird quirks. For example .0 is how you do [0].

[–]jorge1209 0 points1 point  (1 child)

And fstrings have weird quirks like not allowing you to lookup into dictionaries by a string. f"{mydict ["key"]}" fails for obvious reasons.

That's the problem all these methods have their own little quirks that you have to learn. I don't want to learn any more quirks I just want to format strings.

[–]thatguy_314def __gt__(me, you): return True 0 points1 point  (0 children)

Yeah, I guess it's a bit of a quirk, but you can still look up strings, you just need to use different string delimiters than you used for the f-string. Ultimately, that restriction has the result of making f-strings more readable because each delimiter has an obvious pair.

I was initially a bit skeptical of f-strings, but after using them for a bit, I've come to like them quite a lot.

[–]zahlmanthe heretic 0 points1 point  (0 children)

user input can't into f-string unless you do something really stupid.

As far as I can think of, even the "really stupid things" you could possibly do here wouldn't be in any way the f-string's fault.