4

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
  • Scopes are rather different than namespaces. C does not have namespaces, but it does have scopes. C only has local and global scope, Python has some more, most importantly the outer function scope (C does not have nested functions, so there can't be any outer function).
    – Jan Hudec
    Jul 23, 2013 at 9:27
  • 2
    Note, that this has absolutely nothing to do with object oriented. Closures (inner functions keeping access to the outer function variables) are functional programming concept.
    – Jan Hudec
    Jul 23, 2013 at 9:28

1 Answer 1

5

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
  • 3
    The fancy name for these are "closures" Jul 22, 2013 at 19:03
  • What is this @make_bold? I have just reached the classes part in tutorials and haven't seem them till now. Jul 23, 2013 at 8:57
  • 1
    @AseemBansal: It is a decorator. Everything after the @ must result in a function, and that function is passed the function below the line, and the return value of the decorator replaces that function. Effectively, @make_bold added before def hello(...) results in hello = make_bold(hello) right after hello has been evaluated. Jul 23, 2013 at 9:01
  • Instead of It lets you pass functions around that it might be better to use It lets you pass around those functions which. It's confusing because of use around that in the sentence as in Can you go around that corner?. Still reading your answer and trying to understand closures. I'll reply after spending some time on the wikipedia page. Jul 23, 2013 at 9:14
  • @AseemBansal: I can update that, but 'to pass around' has that meaning, quite separate from 'around the corner'. Jul 23, 2013 at 9:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.