Firstly let me clarify that I know C and am learning Python. So my OOPS is kind of bad.
I was reading the official tutorial and found this
Although scopes are determined statically, they are used dynamically. At any time during execution, there are at least three nested scopes whose namespaces are directly accessible:
- the innermost scope, which is searched first, contains the local names
- the scopes of any enclosing functions, which are searched starting with the nearest enclosing scope, contains non-local, but also non-global names
- the next-to-last scope contains the current module’s global names
the outermost scope (searched last) is the namespace containing built-in names
I understand namespaces. I think scopes are the same thing. But I couldn’t figure out what does the sentence about scopes mean? What is the advantage of such an arrangement?
I understand the sentence but couldn’t visualize that. So please don’t say that this is problem with my English.
2
It lets you pass around those functions which use names from the surrounding context in their behaviour.
You see this a lot when defining decorators:
def make_bold(func):
def wrapper(*args, **kw):
return '<b>{}</b>'.format(func(*args, **kw))
return wrapper
@make_bold
def hello(name):
return 'Hello {}!'.format(name)
hello('World') # returns '<b>Hello World!</b>'
Here the wrapper
function accesses func
from the parent function scope; func
is a local variable in the make_bold
function. wrapper
is a closure; wrapper
closes over func
.
You can expand on this a little more by making the decorator configurable:
def format(tag):
def decorator(func):
def wrapper(*args, **kw):
return '<{0}>{1}</{0}>'.format(tag, func(*args, **kw))
return wrapper
return decorator
@format('b')
@format('i')
def hello(name):
return 'Hello {}!'.format(name)
hello('World') # returns '<b><i>Hello World!</i></b>'
Now we have two levels of scoping; tag
comes from the local namespace of format()
, while func
is a argument for the decorator()
function; both are used by wrapper()
.
6