As we have seen, no type declarations are necessary in Python, and variables are essentially just untyped name bindings to objects. As such, they can be rebound – or reassigned – as often as necessary, even to object of different types.
But when we bind a name to an object, where is that binding stored? To answer that question, we must look at scopes and scoping rules in Python.
There are four types of scope in Python, and they are arranged in a hierarchy. Each scope is a context in which names are stored and in which they can be looked up. The four scopes from narrowest to broadest are:
Local - names defined inside the current function.
Enclosing - names defined inside any and all enclosing functions. (This scope isn't important for the contents of this book.)
Global - names defined at the top-level of a module. Each module brings with it a new global scope.
Built-in - names built-in to the Python language through the special builtins module.
Together...