Python language basics 65: keeping state in yield generators


In the previous post we looked at a basic example of using the yield keyword in Python. We saw that yield generator functions are essentially collections that return a certain number of elements when they are enumerated. The elements to be returned – yielded – are not loaded into memory before they are required in a loop. We also said that generator functions can “remember” the state of their variables.

We’ll see an example of what this means in code.

Keeping state

What is meant by “state“? If you are new to programming then this may sound like some mysterious and complex term but it’s quite simple really. The state of an object means what properties the object has “here and now”. E.g. if x is assigned the value of 3 then that is its current state. Later on if its value is reassigned to 10 then the state of x has been changed.

Objects can have multiple properties of course. A house can have an address, the number of rooms, storeys etc. All these properties together make up the state of the object at runtime. You might also hear the expression inconsistent state or invalid state. An object or variable can be in an invalid state if one or more of its properties violates some rule. E.g. normally a price cannot be negative. If the variable x represents a price and it becomes negative due to some error in the code then we say that x is in an inconsistent or invalid state.

Yield functions “remember” the state of their internal variables after each iteration. Consider the following bit of code:

def integer_yielder():
    print("In yield function at counter 100")
    counter = 100
    print("Counter: ", counter)
    yield 1
    print("In yield function at counter + 10")
    counter += 10
    print("Counter: ", counter)
    yield 2
    print("In yield function at counter + 20")
    counter += 20
    print("Counter: ", counter)
    yield 3
    print("In yield function at counter + 30")
    counter += 30
    print("Counter: ", counter)
    yield 4
    print("In yield function at counter + 40")
    counter += 40
    print("Counter: ", counter)

integers = integer_yielder()
for i in integers:
    print("In yielder calling function, printing ", i)

Here’s the output of the code:

In yield function at counter 100
Counter: 100
In yielder calling function, printing 1
In yield function at counter + 10
Counter: 110
In yielder calling function, printing 2
In yield function at counter + 20
Counter: 130
In yielder calling function, printing 3
In yield function at counter + 30
Counter: 160
In yielder calling function, printing 4
In yield function at counter + 40
Counter: 200

The print statements will show you in what order each line of code was executed. If integer_yielder were a normal function then all of its statements would be printed at one go. However, here we see that code execution jumps in and out of the generator function and the latest state of the variable counter is saved.

In the next post we’ll look at a practical implementation of yield generators.

Read all Python-related posts on this blog here.


About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


A great site

iReadable { }

.NET Tips & Tricks

Robin Sedlaczek's Blog

Developer on Microsoft Technologies

HarsH ReaLiTy

A Good Blog is Hard to Find

Softwarearchitektur in der Praxis

Wissenswertes zu Webentwicklung, Domain-Driven Design und Microservices

the software architecture

thoughts, ideas, diagrams,enterprise code, design pattern , solution designs

Technology Talks

on Microsoft technologies, Web, Android and others

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

Anything around ASP.NET MVC,WEB API, WCF, Entity Framework & AngularJS

Cyber Matters

Bite-size insight on Cyber Security for the not too technical.

Guru N Guns's

OneSolution To dOTnET.

Johnny Zraiby

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

%d bloggers like this: