Scope of function inside the function (understanding recursion)
Question: What is the scope of the function itself inside the function in python? My
question arises because I finally thought about venturing into recursion (
though I am not competent enough to understand it fully). I am using Eclipse
(PyDev) and inside the class, for example:

A simple recursion example for factorial widespread in every book is:

    
    
    def factorial(n):
           if (n==0):
               return 1
           else:
    
               return n*factorial(n-1)
    

In another example, inside the class:

    
    
    class test:
    
        def factorial(self,n):
           if (n==0):
               return 1
           else:
               return n*factorial(n-1)
    

Do I have to use `self.factorial(n-1)`? ( I guess, I should because PyDev is
showing unidentified variable when I don't). Why is the reference to the
object itself is needed in this case? Am I missing some important thing I
should understand here.


Answer: `factorial` in your first example is a global function. The fact that you call
it recursively, does not change that you still first need to look up the
function object to be able to call it.

In other words, the current function being called is not in any way special.
`factorial` is still a name that needs to be dereferenced, and it doesn't
matter that that name happens to reference to the function being executed.

Thus, in your second example, where `factorial` is instead a method, there is
no global reference to that method. Instead, you find it like any other method
on the class, through the `self` reference.

When you define a function, Python stores a reference to that new function
object in the name you gave it, in the current scope. In a global scope that
means that `def foo()` becomes a global name `foo` bound to a function object.
You can _break_ recursion by removing that name:

    
    
    >>> def foo(): return foo()  # infinite recursion
    ...
    >>> def foo(): return foo()  # infinite recursion
    ... 
    >>> foo
    <function foo at 0x108e4b500>
    >>> bar = foo
    >>> del foo
    >>> foo
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'foo' is not defined
    >>> bar
    <function foo at 0x108e4b500>
    >>> bar()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 1, in foo
    NameError: global name 'foo' is not defined
    

Note the `NameError` here; I deleted `foo` from the global namespace, but
still have a reference in `bar`, which I can call. But the function itself,
when executed, cannot find the global name `foo`.

Python functions otherwise, have no reference to themselves. From _inside_ the
function, you cannot retrieve the function object itself, not reliably. The
best you can do is get the original function name:

    
    
    >>> def foo():
    ...     return sys._getframe(0).f_code.co_name
    ... 
    >>> foo()
    'foo'
    >>> bar = foo
    >>> bar()
    'foo'
    

but that does not give you a guarantee that you can still access that function
object through that name.

