3 ms·
Most excellent! I love f-strings and replaced all the various other string interpolation instances in my code with them, but they have the significant issue tha
by kstrauser 2y ago
Most excellent! I love f-strings and replaced all the various other string interpolation instances in my code with them, but they have the significant issue that you can't defer evaluating them. For instance, you can write:
>>> template = 'Hello, {name}'
>>> template.format(name='Bob')
'Hello, Bob'
Until this, there wasn't a way to use f-strings formatting without interpolating the results at that moment:
>>> template = f'Hello, {name}'
Traceback (most recent call last):
File "<python-input-5>", line 1, in <module>
template = f'Hello, {name}'
^^^^
NameError: name 'name' is not defined
It was annoying being able to use f-strings almost everywhere, but str.format in enough odd corners that you have to put up with it.
- ossopite 2y agoI'm not sure if t-strings help here? unless I misread the PEP, it seems like they still eagerly evaluate the interpolations. There is an observation that you can use `lambda` inside to delay evaluation of an interpolation, but I think this lambda captures any variables it uses from the context.
- tylerhou 2y agoYou could do something like t”Hello, {“name”}” (or wrap “name” in a class to make it slightly less hacky).
- notpushkin 2y ago> An early version of this PEP proposed that interpolations should be lazily evaluated. [...] This was rejected for several reasons [...] Bummer. This could have been so useful: statement_endpoint: Final = "/api/v2/accounts/{iban}/statement" (Though str.format isn’t really that bad here either.)
- LordShredda 2y agoWould be useful in that exact case, but would be an absolute nightmare to debug, on par with using global variables as function inputs
- notpushkin 2y agoYeah, to be honest, every time this comes to mind I think “wow, this would be really neat!”, then realize just using .format() explicitly is way easier to read.
- nhumrich 2y agoThere was a very very long discussion on this point alone, and there are a lot of weird edge cases, and led to weird syntax things. The high level idea was to defer lazy eval to a later PEP if its still needed enough. There are a lot of existing workarounds in the discussions if you are interested enough in using it, such as using lambdas and t-strings together.
- o11c 2y agoI do think that people are far too hesitant to bind member functions sometimes: statement_endpoint: Final = "/api/v2/accounts/{iban}/statement".format (it's likely that typecheckers suck at this like they suck at everything else though)
- davepeck 2y ago> I'm not sure if t-strings help here? That's correct, they don't. Evaluation of t-string expressions is immediate, just like with f-strings. Since we have the full generality of Python at our disposal, a typical solution is to simply wrap your t-string in a function or a lambda. (An early version of the PEP had tools for deferred evaluation but these were dropped for being too complex, particularly for a first cut.)
- krick 2y agoAnd that actually makes "Template Strings" a misnomer in my mind. I mean, deferred (and repeated) evaluation of a template is the thing that makes template a template. Kinda messy PEP, IMO, I'm less excited by it than I'd like to be. The goal is clear, but the whole design feels backwards.
- davepeck 2y agoNaming is hard; for instance, JavaScript also has its own template strings, which are also eagerly evaluated.
- actinium226 2y ago> There is an observation that you can use `lambda` inside to delay evaluation of an interpolation, but I think this lambda captures any variables it uses from the context. Actually lambda works fine here >>> name = 'Sue' >>> template = lambda name: f'Hello {name}' >>> template('Bob') 'Hello Bob'
- skeledrew 2y agoLambda only captures variables which haven't been passed in as argument.
- ratorx 2y agoDelayed execution is basically equivalent to a function call, which is already a thing. It also has basically the same API as point of use and requires maybe 1 extra line.
- deleted 2y ago[deleted]
- foobahify 2y agoThe issue was solved by having a rich and Turing complete language. I am not huge on adding language features. This seems like userland stuff.
- actinium226 2y agoI tend to agree. I think it's easy enough to use a lambda in this case >>> template = lambda name: f'Hello {name}' >>> template('Bob')
- a3w 2y agoI read 'most excellent' in the Bill and Ted voice
- kstrauser 2y agoThen it worked.
- davepeck 2y agoPEP 750 doesn't directly address this because it's straightforward to simply wrap template creation in a function (or a lambda, if that's your style): def my_template(name: str) -> Template: return t"Hello, {name}"
- catlover76 2y ago[dead]
- paulddraper 2y agoYou gravely misunderstand. The point of evaluation of the expressions is the same. >>> template = t'Hello, {name}' is still an error if you haven't defined name. BUT the result of a t-string is not a string; it is a Template which has two attributes: strings: ["Hello, ", ""] interpolations: [name] So you can then operate on the parts separately (HTML escape, pass to SQL driver, etc.).