Question

There is class definition in django of view in view.generic.base

class View(object):
    ...
    def as_view(cls, **initkwargs):
        """ 
        Main entry point for a request-response process.
        """
        ...

        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            if hasattr(self, 'get') and not hasattr(self, 'head'):
                self.head = self.get
            self.request = request
            self.args = args
            self.kwargs = kwargs
            return self.dispatch(request, *args, **kwargs)

        # take name and docstring from class
        update_wrapper(view, cls, updated=())

        # and possible attributes set by decorators
        # like csrf_exempt from dispatch
        update_wrapper(view, cls.dispatch, assigned=())
        return view

It should return a function like view(request, *args, **kwargs). Notice there is a variable in 'def view', which is 'cls'.

Suppose we run:

tmp = View.as_view(), how will tmp(request, *args, **kwargs) know what is the value of cls?


THIS IS THE SIMPLIFIED SITUATION!!!!!

Say python code like this:

>>> def func1(a):
...     def func2(b):
...         c = a + b
...         print c
...     return func2
... 
>>> func3 = func1(3)
>>> func3(1)
4
>>> func4 = func1(4)
>>> func3(1)
4
>>> func4(1)
5
>>> func3.a=5
>>> func3(1)
4
>>> func1.a=5
>>> func3(1)
4

What is 'a' in def of func3 actually and how did func3 get it?


Update1:

Thanks for answering. The question was not totally expressed.

I think, when we call func3 = func1(3), we have two objects in the program, code of func1, object(symbol table) of called func1(3).

My questions are:

  1. Is there an func2() object produced by calling code func1(), or the value of func3 is just a pointer to a member of the produced func1(3) which is the instruction of func2()?

  2. Is the a of calling func3(1) in func1(3), or the object of func2()?

Was it helpful?

Solution 2

Let me explain what your code does

>>> def func1(a):
...     def func2(b):
...         c = a + b
...         print c
...     return func2
... 

This will create one function func1 which return you another function func2. func2 is local for func1

>>> func3 = func1(3)

This will create variable func3 and value of func3 is func2. So when you print value of func3 it will return function.

>>> func3
<function func2 at 0x7fd29fcb66e0>

If you try to access func3.a then it will not return you 1 because a is not a attribute of func2.

>>> func3.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'function' object has no attribute 'a'

a is local variable, so you cant access it. When you call func3, it will call func2 with a as 1.

>>> func3(1)
4

So this will call func2(1) where a is 3 in local func2.

OTHER TIPS

You have created a closure by returning a function from another function.

Using your simplified example, any variables that were in scope, and were referenced from your inner function func2 will remain in scope for as long as func2 continues to exist.

So any variables declared inside func1 (including function parameters such as a) are always accessible to func2 even after func1 ends.

The value that a has when func2 runs will be whatever value you passed to func1 to produce that particular instance of func2

I've run the same python program with some changes :

>>> def func1(a):
...     def func2(b):
...             c = a + b
...             print c
...             print a
...             print b
...     return func2
... 
>>> func3 = func1(3)
>>> func3(1)
4
3
1
  1. First of all when you call fun1(3), then the fun1 returns fun2, something like this

def fun2(b):
    c = 3 + b
    print c
    print 3
    print b


2. Now, when you call function func3(1), you are effectively calling func2(1)

It's the way it should work :)

For start, there is nothing recursive going on here, I guess you mean inner function definition. Inner function has access to surrounding scope (which is also called a closure). When you get your copy of function func3 it will have access to variables defined in outer function including parameter it's been called with

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top