[Python-Dev] Subtle difference between f-strings and str.format()
Nick Coghlan
ncoghlan at gmail.com
Fri Mar 30 07:41:46 EDT 2018
On 30 March 2018 at 21:16, Nathaniel Smith <njs at pobox.com> wrote:
> On Fri, Mar 30, 2018 at 3:29 AM, Serhiy Storchaka <storchaka at gmail.com> wrote:
>> 29.03.18 18:06, Terry Reedy пише:
>>>
>>> On 3/28/2018 11:27 AM, 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.
>>>
>>>
>>> Perhaps Ref 3.3.1 object.__bool__ entry, after " should return False or
>>> True.", should say something like "Should not have side-effects, as
>>> redundant bool calls may be optimized away (bool(bool(ob)) should have the
>>> same result as bool(ob))."
>>
>>
>> Do you meant that it should be idempotent operation? Because bool(bool(ob))
>> always have the same result as bool(ob)) if bool(ob) returns True or False.
>
> 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.
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
More information about the Python-Dev
mailing list