[Python-Dev] Subtle difference between f-strings and str.format()
Chris Jerdonek
chris.jerdonek at gmail.com
Fri Mar 30 13:33:07 EDT 2018
On Fri, Mar 30, 2018 at 4:41 AM, Nick Coghlan <ncoghlan at gmail.com> wrote:
> On 30 March 2018 at 21:16, Nathaniel Smith <njs at pobox.com> wrote:
>> And bool(obj) does always return True or False; if you define a
>> __bool__ method that returns something else then bool rejects it and
>> raises TypeError. So bool(bool(obj)) is already indistinguishable from
>> bool(obj).
>>
>> However, the naive implementation of 'if a and True:' doesn't call
>> bool(bool(a)), it calls bool(a) twice, and this *is* distinguishable
>> by user code, at least in principle.
>
> For example:
>
> >>> class FlipFlop:
> ... _state = False
> ... def __bool__(self):
> ... result = self._state
> ... self._state = not result
> ... return result
> ...
> >>> toggle = FlipFlop()
> >>> bool(toggle)
> False
> >>> bool(toggle)
> True
> >>> bool(toggle)
> False
> >>> bool(toggle) and bool(toggle)
> False
> >>> toggle and toggle
> <__main__.FlipFlop object at 0x7f35293604e0>
> >>> bool(toggle and toggle)
> True
>
> So the general principle is that __bool__ implementations shouldn't do
> anything that will change the result of the next call to __bool__, or
> else weirdness is going to result.
I don't think this way of stating it is general enough. For example,
you could have a nondeterministic implementation of __bool__ that
doesn't itself carry any state (e.g. flipping the result with some
probability), but the next call could nevertheless still return a
different result. So I think Nathaniel's way of stating it is probably
better:
> If we want to change the language spec, I guess it would be with text
> like: "if bool(obj) would be called twice in immediate succession,
> with no other code in between, then the interpreter may assume that
> both calls would return the same value and elide one of them".
--Chris
More information about the Python-Dev
mailing list