Yield after the return in Python function.
Terry Reedy
tjreedy at udel.edu
Mon Apr 5 15:00:53 EDT 2021
On 4/5/2021 1:53 PM, Chris Angelico wrote:
> On Tue, Apr 6, 2021 at 3:46 AM Terry Reedy <tjreedy at udel.edu> wrote:
>> *While 'a and not a' == False in logic, in Python it might raise
>> NameError. But that would still mean that it is never True, making
>> 'yield 0' still unreachable.
When I wrote that, I knew I might be missing something else.
> And even just the lookup can have side effects, if your code is
> pathologically stupid.
Or pathologically clever.
>>>> class Wat(dict):
> ... def __missing__(self, key):
> ... global count
> ... count -= 1
> ... return count
'__missing__' is new since I learned Python. I barely took note of its
addition and have never used it. Thanks for the example of what it can
do. One could also make it randomly return True or False.
>>>> count = 2
>>>> eval("print(a and not a)", Wat(print=print))
> True
>
> So Python can't afford to treat this as dead code.
This gets to the point that logic and math are usually atemporal or at
least static (as in a frozen snapshot), while computing is dynamic. In
algebra, the canon is that all instances of a variable are replaced by
the same value.
Python *could* do the same for expresssions: load 'a' (in this case)
once into a register or stack slot and use that value consistently
throughout the expression. Replacing the eval with the following exec
has the same effect.
exec("tem=a; print(tem and not tem)", Wat(print=print))
# print False
In this example, one could disable the binding with __setitem__
(resulting in printing 0), but python code cannot disable internal
register or stack assignments.
--
Terry Jan Reedy
More information about the Python-list
mailing list