Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't Python access a subfunction from outside?

Tags:

python

def A():
    def B():
        #do something

a = A()
a.B()

Why isn't the above (such simple code) possible in Python? Is there a 'pythonic' (legible, unsurprising, non-hacky) workaround that does not turn A() into a class?

Edit 1: The above was explained to me that B is local to A, thus it only exists as long as A is being evaluated. So if we make it global (and be sure not to have it overriden), then why doesn't this work?

def A():
    def B():
        #do something
    return A()

a = A()
a.B()

It says it's returning a 'NoneType' object.

like image 337
FizzledOut Avatar asked Oct 06 '12 05:10

FizzledOut


People also ask

How do you call an inner function from the outside function in Python?

Defining an Inner Function In the above example, function2() has been defined inside function1() , making it an inner function. To call function2() , we must first call function1() . The function1() will then go ahead and call function2() as it has been defined inside it. The code will return nothing when executed!

How do you access the variable of a nested function in Python?

A function defined inside another function is called a nested function. Nested functions can access variables of the enclosing scope. In Python, these non-local variables are read-only by default and we must declare them explicitly as non-local (using nonlocal keyword) in order to modify them.


2 Answers

Because a function definition just creates a name in the local namespace. What you are doing is no different than:

def f():
    a = 2

and then asking why you can't access a from outside the function. Names bound inside a function are local to the function.

In addition, your proposed code is strange. when you do a = f(), you are setting a to the return value of the function. Your function returns nothing, so you can't hope to access anything through the return value. It is possible to return the inner function directly:

def f():
   def g():
      return "blah"
   return g

>>> func = f()
>>> func()
'blah'

And this can indeed be useful. But there isn't a generic way to access things inside the function from outside except by modifying global variables (which is usually a bad idea) or returning the values. That's how functions work: they take inputs and return outputs; they don't make their innards available to the outside word.

like image 134
BrenBarn Avatar answered Sep 27 '22 17:09

BrenBarn


To call B with the syntax you want, use:

def A():
    def B():
        print("I'm B")
    A.B = B
    return A

a = A()
a.B()
A.B()
like image 38
panda-34 Avatar answered Sep 27 '22 16:09

panda-34