How to write Python generator function that never yields anything

generator, python, yield

Solution

For maximum readability and maintainability, I would prioritize a construct which goes at the top of the function. So either

- your original `if False: yield` construct, but hoisted to the very first line, or

- a separate decorator which adds generator behavior to a non-generator callable.

(That's assuming you didn't just need a callable which did something and then returned an empty iterable/iterator. If so then you could just use a regular function and `return ()`/`return iter(())` at the end.)

Imagine the reader of your code sees:

def name_fitting_what_the_function_does():
    # We need this function to be an empty generator:
    if False: yield

    # that crucial stuff that this function exists to do

Having this at the top immediately cues in every reader of this function to this detail, which affects the whole function - affects the expectations and interpretations of this function's behavior and usage.

How long is your function body? More than a couple lines? Then as a reader, I will feel righteous fury and condemnation towards the author if I don't get a cue that this function is a generator until the very end, because I will probably have spent significant mental cost weaving a model in my head based on the assumption that this is a regular function - the first `yield` in a generator should ideally be immediately visible, when you don't even know to look for it.

Also, in a function longer than a few lines, a construct at the very beginning of the function is more trustworthy - I can trust that anyone who has looked at a function has probably seen its first line every time they looked at it. That means a higher chance that if that line was mistaken or broken, someone would have spotted it. That means I can be less vigilant for the possibility that this whole thing is actually broken but being used in a way that makes the breakage non-obvious.

If you're working with people who are sufficiently fluently familiar with the workings of Python, you could even leave off that comment, because to someone who immediately remembers that `yield` is what makes Python turn a function into a generator, it is obvious that this is the effect, and probably the intent since there is no other reason for correct code to have a non-executed `yield`.

Alternatively, you could go the decorator route:

@generator_that_yields_nothing
def name_fitting_what_the_function_does():
    # that crucial stuff for which this exists


def generator_that_yields_nothing(wrapped):
    @functools.wraps(wrapped)
    def wrapper_generator():
        if False: yield
        wrapped()
    return wrapper_generator

Problem

I want to write a Python generator function that never actually yields anything. Basically it's a "do-nothing" drop-in that can be used by other code which expects to call a generator (but doesn't always need results from it). So far I have this: ``` def empty_generator(): # ... do some stuff, but don't yield anything if False: yield ``` Now, this works OK, but I'm wondering if there's a more expressive way to say the same thing, that is, declare a function to be a generator even if it never yields any value. The trick I've employed above is to show Python a yield statement inside my function, even though it is unreachable.

Original source