Learning python 5ed
Chapter 17: Scopes
namespace vs scope
namespace - place where names live in. Python creates, changes, or looks up name in a namespace (name here can be variables’ name, functions’ name… etc).
scope - name’s visibility, it refers to a namespace. The location of a name’s assignment determines the scope of the name’s visibility.
namespace and scope seem a bit confuse here. but let say namespace as a box contains names: there is a builtin namespace contains names like open, getattr, setattr and so on; when in a module, there will be a module namespace which contains global names from that module; when in a function call, there will a function namespace contains names local to that funtion.
so, namespace is a box contains names. Scope defines which box you can see from parts of the program (that’s why name’s visibility). It defines where you could use a name without using any prefix.
In Python, almost everything related to names, including scope, happens at assignment time. Python uses the location of the assigment of a name to associate it with (bind it to) a particular namespace. That is, the place of name assigment determines the namespace it will live in and its scope of visibility.
Besides packaging code for reuse, functions add an extra namespace layer to minimize the potential for collisions among variables of the same name - by default, all names assigned inside a function are associated with that function’s namespace, and no other.
Three different scopes:
- If a variable is assigned inside a def, it is local to that function.
- If a variable is assigned in an enclosing def, it is nonlocal to nested functions.
- If a variable is assigned outside all defs, it is global to the entire file.
This is lexical scoping because variable scopes are determined entirely by the locations of the variables.
Any type of assignment within a function classifies a name as local. This includes = statements, module names in import, function names in def, function argument names, and so on.
in-place changes to objects do not classify names as locals; only actual name assignments do.
For instance, if the name L is assigned to a list at the top level of a module, a statement L = X within a function will classify L as a local, but L.append(X) will not. In the latter case, we are changing the list object that L references, not L itself - L is found in the global scope as usual, and Python happily modifies it without requiring a global (or nonlocal) declaration.
Distinction between names and objects: changing an object is not an assignment to a name.
Name Resolution: The LEGB Rule
- Name assignments create or change local names by default.
- Name references search at most four scopes: local, then enclosing functions (if any), then global, then built-in.
- Names declared in global and nonlocal statements map assigned names to enclosing module and enclosing function scopes, respectively.
LGBT rules are applied for references or usage (not assignments) of simple variables
Other Python scopes:
- Temporary variables in comprehension
- Exception reference variable in try handlers
- Local scopes in class statements
The built-in scope
The built-in scope is just a built-in module called
builtins (3.x) or
__builtins__ (with the s) is preset in most global scopes, including the interactive session, to reference the module known as
builtins in 3.X and
__builtin__ in 2.X
global and nonlocal
Concern with this only when do assingments not references, references are simple follow LEGB rule.
The 3.X nonlocal statement allow enclosing scope state changes. In 2.X, enclosing scopes are read-only.
- Minimize Global Variables
- Minimize Cross-File Changes
Function factory or closure
Closure is functional programming technique in which nested function remember variables from its enclosing functions or environment (state retention).
State retention between function call
- using global variable
- class instance attribute
- using enclosing scope
- function default argument (with enclosing scope, it is not nescessery to use defaul argument to retain state between function call, but loop variables still required)
- function attribute
Chapter 18: Arguments
Arguements are passed by reference
In general, should avoid mutable argument changes