yield в функции возвращает объект-генератор. Генератор - это итерируемый объект, который производит значения "по требованию", а не хранит их все в памяти сразу.
Оператор yield в Python используется внутри функций для создания генераторов.  Вместо того, чтобы возвращать одно значение и завершать выполнение, функция с yield возвращает объект-генератор. Этот объект можно использовать для итерации по последовательности значений, которые функция генерирует.
Когда функция с yield вызывается, она не выполняет код функции сразу. Вместо этого она возвращает объект-генератор.  При каждой итерации по этому генератору (например, с помощью цикла for или функции next()), функция выполняется до следующего оператора yield.
Когда yield встречается, функция "приостанавливает" свое выполнение, сохраняя свое состояние (значения переменных, текущую точку выполнения и т.д.). Значение, указанное после yield, возвращается генератором в качестве следующего элемента последовательности.  Затем, при следующем запросе элемента (например, при следующей итерации цикла), функция возобновляет свое выполнение с того места, где она была приостановлена, продолжая до следующего yield (или до конца функции).
Если функция достигает конца своего тела (или встречает оператор return без значения), генератор останавливается, и попытка получения следующего значения вызовет исключение StopIteration.
В итоге, yield возвращает объект-генератор, который позволяет итерировать по последовательности значений, генерируемых функцией, "по требованию" (lazy evaluation), что может быть очень эффективным для работы с большими объемами данных или бесконечными последовательностями.
Пример:
        
def my_generator(n):
    for i in range(n):
        yield i * 2
gen = my_generator(3)  # gen - это объект-генератор
print(next(gen))  # Выведет 0
print(next(gen))  # Выведет 2
print(next(gen))  # Выведет 4
#print(next(gen))  # Вызовет StopIteration, т.к. генератор закончился