Remix.run Logo
kstrauser 5 days ago

Yes. If a function contains the yield statement, calling that function returns a generator instead of executing its body. For example, here's defining and calling a regular function:

  >>> def foo_function():
  ...     print('In a function!')
  ...     return
  ...
  >>> foo_function()
  In a function!
And here's defining and calling a generator:

  >>> def foo_generator():
  ...     print('In a generator!')
  ...     return
  ...     yield
  ...
  >>> foo_generator()
  <generator object foo_generator at 0x10321aa40>
  >>> next(foo_generator())
  In a generator!
  Traceback (most recent call last):
    File "<python-input-6>", line 1, in <module>
      next(foo_generator())
      ~~~~^^^^^^^^^^^^^^^^^
  StopIteration
Notice that the generator's body isn't evaluated until you consume the generator. StopIteration isn't actually an error in usual cases. It just says that the generator doesn't have any more values to return and has exited. For example, that's how Python's for-loop works:

  >>> for _ in foo_generator():
  ...     continue
  ...
  In bar!
Here it executes the generator's body (including the print() call) until it gets to the return statement. Because it's a generator, it returns as normal and then raises a StopIteration exception, which tells the loop to stop looping.