[Python-ideas] Control Flow - Never Executed Loop Body

Sven R. Kunze srkunze at mail.de
Tue Mar 22 08:27:05 EDT 2016


On 22.03.2016 13:16, Chris Angelico wrote:
> On Tue, Mar 22, 2016 at 11:07 PM, Sven R. Kunze <srkunze at mail.de> wrote:
>> However, I assume that when I do "object()" I got something unique among all
>> other objects. So,
>>
>> item = sentinel = object()
>> for item in collection:
>>      main_suite(item)
>> if item is sentinel:
>>      empty_suite()
>>
>> Is still quite correct, right?
> Sure it is. Perfectly correct.
>
>>>> def nope():
> ...     item = sentinel = object()
> ...     for item in locals().values():
> ...         print("We have:", item)
> ...     if item is sentinel:
> ...         print("We have no items.")
> ...
>>>> nope()
> We have: <object object at 0x7f17b1c6b0a0>
> We have: <object object at 0x7f17b1c6b0a0>
> We have no items.
> An iterator can return *any* *object*. That's why Python uses an
> exception (StopIteration) to signal the absence of an object.

Oh, you are right. That's definitely an ugly edge case. Any proposed 
solution should just work given the simplicity of the problem.

> More reliable is to use that absence, either by exception or by
> probing a dictionary's keys:
>
> def better():
>      # Make sure item is unbound
>      try: del item
>      except NameError: pass
>      for item in locals().values():
>          print("We have:", item)
>      if 'item' not in locals():
>          print("We have no items.")

Interesting.

> But now we're getting into the realm of ugly code to deal with edge
> cases. Like with "yield from", language support can be justified when
> there's a simple and obvious *but imperfect* way to do something
> ("yield from x" is not the same as "for item in x: yield item").

Exactly. Despite the fact that "yield from" is shorter it can handle 
edge cases more beautiful.

Best,
Sven


More information about the Python-ideas mailing list