Closures

A closurearrow-up-right is a function that references variables from outside its own function body. The function definition and its environment are bundled together into a single entity.

Put simply, a closure is just a function that keeps track of some values from the place where it was defined, no matter where it is executed later on.

Example

The concatter() function returns a function called doc_builder (yay higher-order functions!) that has a reference to an enclosed doc value

def concatter():
	doc = ""
	def doc_builder(word):
		# "nonlocal" tells Python to use the 'doc'
		# variable from the enclosing scope
		nonlocal doc
		doc += word + " "
		return doc
	return doc_builder

# save the returned 'doc_builder' function
# to the new function 'harry_potter_aggregator'
harry_potter_aggregator = concatter()
harry_potter_aggregator("Mr.")
harry_potter_aggregator("and")
harry_potter_aggregator("Mrs.")
harry_potter_aggregator("Dursley")
harry_potter_aggregator("of")
harry_potter_aggregator("number")
harry_potter_aggregator("four,")
harry_potter_aggregator("Privet")

print(harry_potter_aggregator("Drive"))
# Mr. and Mrs. Dursley of number four, Privet Drive

When concatter() is called, it creates a new "stateful" function that remembers the value of its internal doc variable. Each successive call to harry_potter_aggregator appends to that same doc.

nonlocal

Python has a keyword called nonlocalarrow-up-right that's required to modify a variable from an enclosing scope. Most programming languages don't require this keyword, but Python does.

When the definition of a function or class is nested (enclosed) within the definitions of other functions, its nonlocal scopes are the local scopes of the enclosing functions. The nonlocalarrow-up-right statement causes the listed identifiers to refer to names previously bound in nonlocal scopes. It allows encapsulated code to rebind such nonlocal identifiers. If a name is bound in more than one nonlocal scope, the nearest binding is used. If a name is not bound in any nonlocal scope, or if there is no nonlocal scope, a SyntaxErrorarrow-up-right is raised.

The nonlocalarrow-up-right statement applies to the entire scope of a function or class body. A SyntaxErrorarrow-up-right is raised if a variable is used or assigned to prior to its nonlocal declaration in the scope.

Assignment

Doc2Doc keeps track of how many words are in a collection of documents.

Complete the word_count_aggregator function. It should return a function that calculates the number of words in its input (doc, a string). It should then add that number to an enclosed count value and return the new count. In other words, it keeps a running total of the count variable within a closure.

Solution

How The Code Works

  1. count = 0 β†’ Initializes a variable to store the running total of words.

  2. calculator(doc) β†’ Defines an inner function that:

    • Uses nonlocal count to modify the outer variable.

    • Splits the input string (doc) into words and counts them.

    • Adds the count to the running total.

    • Returns the updated count.

  3. Returns calculator β†’ The function returned maintains the count variable across multiple calls.

Last updated