Python generators are a simple way of creating iterators. Generators are special type of functions that allow you to declare a function that behaves like an iterator, i.e. it can be used in a for loop.
The difference between generator functions and regular functions is that while regular function runs, completes and sends back a result, a generator function can pause after delivering a result, maintain its state, and then continue from where it left off.
The advantage of using generators is that they don’t store all results in memory but produce them on the fly, saving memory when you are dealing with large data.
Here is a simple generator function:
```
def my_generator():
yield 1
yield 2
yield 3
```
If you call the function `my_generator()`, it will return a generator object, not the values 1, 2, and 3. You can access the values with the built-in Python function `next()`, or by using the generator in a loop like below:
```
for num in my_generator():
print(num)
```
Which will output:
1
2
3
Here, `yield` is used where you would usually use `return` in a function. When the Python yield statement is hit, the program suspends function execution and returns the yielded value to the caller. When the function is called again it resumes execution immediately after where it left off, with the same variable states it had before yielding.