[Python-Dev] Subtle difference between f-strings and str.format() (original) (raw)

Chris Angelico rosuav at gmail.com
Thu Mar 29 10🔞15 EDT 2018


On Fri, Mar 30, 2018 at 1:08 AM, Chris Angelico <rosuav at gmail.com> wrote:

On Thu, Mar 29, 2018 at 11:28 PM, Steven D'Aprano <steve at pearwood.info> wrote:

On Wed, Mar 28, 2018 at 06:27:19PM +0300, Serhiy Storchaka wrote:

The optimizer already changes semantic. Non-optimized "if a and True:" would call bool(a) twice, but optimized code calls it only once. I don't understand this. Why would bool(a) be called twice, and when did this change? Surely calling it twice would be a bug. I just tried the oldest Python 3 I have on this computer, 3.2, and bool is only called once. Technically not bool() itself, but the equivalent. Here's some similar code:

Wow, I'm good. Premature send much? Nice going, Chris. Let's try that again. Here's some similar code:

def f(a): ... if a and x: ... print("Yep") ... class Bool: ... def bool(self): ... print("True?") ... return True ... x = 1 f(Bool()) True? Yep

This is, however, boolifying a, then boolifying x separately. To bool a twice, you'd need to write this instead:

def f(a): ... if a or False: ... print("Yep") ...

In its optimized form, this still only boolifies a once. But we can defeat the optimization:

def f(a): ... cond = a or False ... if cond: ... print("Yep") ... f(Bool()) True? True? Yep

The "or False" part implies a booleanness check on its left operand, and the 'if' statement performs a boolean truthiness check on its result. That means two calls to bool in the unoptimized form. But it gets optimized, on the assumption that bool is a pure function. The version assigning to a temporary variable does one check before assigning, and then another check in the 'if'; the same thing without the temporary skips the second check, and just goes ahead and enters the body of the 'if'.

Technically that's a semantic change. But I doubt it'll hurt anyone.

ChrisA



More information about the Python-Dev mailing list