You cannot, not unless fib returns inner somehow. inner is essentially a local variable inside the scope of fib and you can't access a function's locals from outside of it. (That wouldn't even make sense, since the locals don't exist except when the function is running. Think about it -- would it make sense to access fib's c variable from outside of the function?)
python - Accessing a function within a function(nested function?) - Stack Overflow
[Python] | How to call nested functions
Call nested function from another function in python? - Stack Overflow
Call Nested Function in Python - Stack Overflow
You cannot, not unless fib returns inner somehow. inner is essentially a local variable inside the scope of fib and you can't access a function's locals from outside of it. (That wouldn't even make sense, since the locals don't exist except when the function is running. Think about it -- would it make sense to access fib's c variable from outside of the function?)
Do not use the following.
[...]
>>> j = Fibonacci(0,1,2)
>>> j.fib()
0 1 1
>>> # dark magic begins!
>>> import new
>>> new.function(j.fib.im_func.func_code.co_consts[2],{})(None)
Damn it! Just print already!
You can tell simply by looking at it that it's not really Python, and for that matter it isn't really calling the "inner" function itself, it's simply creating a new function like it. I also didn't bother setting the globals 'correctly', because this is a terrible thing to do in the first place..
[I should mention that the point of the above is to note that the idea that you can't access internals from outside isn't strictly true, though it's almost never a good idea. Exceptions include interpreter-level code inspections, etc.]
Unclean! Unclean!
This is the code I am trying to run:
x = 1
def f1():
x = 2
def f2():
global x
x = 3
print(x)
f1()
print(x)
f2()
print(x)Output:
1
1
Traceback (most recent call last):
f2()
NameError: name 'f2' is not defined
What I meant to do was call the f2() function but then it showed an error.
My question is how do I call the f2() function outside the nested block?
When you do this, function b is defined locally within a. This means that it cannot be accessed by default outside of a. There are two main ways to solve this, but both involve modifying a:
The
globalkeyword (not recommended)def a(): global b def b(): print("hi")Here the
globalkeyword setsbup as a global variable, so that you can then access it by calling it normally from withinc. This is generally frowned upon.Returning the function from
aand passing it tocdef a(): def b(): print("hi") return b def c(b): #your codeThen, when you call
c, you should passbto it, whichawill have returned. You can either do so thus:b = a() c(b)Or you can simply call
aevery time you callc, thus:c(a())If you choose to do this, you can then define
cthus:def c(): b = a() #your code herewhich would allow you to simply call
cnormally, thus:`c()`
This is not possible due to the way that Python scope works. b() is local to a(), and so does not exist within c().
EDIT: commenter is correct, the suggestion I initially gave doesn't work -- so this definitely just isn't possible.
I assume do_this and do_that are actually dependent on some argument of foo, since otherwise you could just move them out of foo and call them directly.
I suggest reworking the whole thing as a class. Something like this:
class Foo(object):
def __init__(self, x, y):
self.x = x
self.y = y
def do_this(self):
pass
def do_that(self):
pass
def __call__(self):
self.do_this()
self.do_that()
foo = Foo(x, y)
foo()
foo.do_this()
These previous answers, telling you that you can not do this, are of course wrong. This is python, you can do almost anything you want using some magic code magic.
We can take the first constant out of foo's function code, this will be the do_this function. We can then use this code to create a new function with it.
see https://docs.python.org/2/library/new.html for more info on new and https://docs.python.org/2/library/inspect.html for more info on how to get to internal code.
Warning: it's not because you CAN do this that you SHOULD do this, rethinking the way you have your functions structured is the way to go, but if you want a quick and dirty hack that will probably break in the future, here you go:
import new
myfoo = new.function(foo.func_code.co_consts[1],{})
myfoo(x,y) # hooray we have a new function that does what I want
UPDATE: in python3 you can use the types module with foo.__code__:
import types
myfoo = types.FunctionType(foo.__code__.co_consts[1], {})
myfoo() # behaves like it is do_this()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: do_this() missing 2 required positional arguments: 'x' and 'y'
>>> def main():
... def sub():
... a=5
... print a
...
>>> main.__code__.co_consts
(None, <code object sub at 0x2111ad0, file "<stdin>", line 2>)
>>> exec main.__code__.co_consts[1]
5
You can if you return the inner function as a value
>>> def main():
... def sub():
... a = 5
... print a
... return sub
...
>>> inner = main()
>>> inner()
5
or you can attach it to main as a property (functions are objects after all):
>>> def main():
... def sub():
... a = 5
... print a
... main.mysub = sub
...
>>> main()
>>> main.mysub()
5
but you better document your very good reason for doing this, since it will almost certainly surprise anyone reading your code :-)
As the function does not exists until the function call (and only exists during it), you cannot access it.
If the closure is not important, you can build the inner function directly from the code constant placed inside the outer function:
inner = types.FunctionType(myFunc.__code__.co_consts[1], globals())
The position inside the const values of the function may vary...
This solution does not require calling myFunc.
what you could do is either return the function or attach it to its parent when called ...
>>> def myFunc( a, b ):
... def innerFunc( c ):
... print c
... innerFunc( 2 )
... myFunc.innerFunc = innerFunc
... print a, b
...
>>>
>>> myFunc(1,2)
2
1 2
>>> myFunc.innerFunc(3)
3
>>>
though apparently you can access the source code using a special attribute, that function objects have ... myFunc.func_code though this seems to be accessing some serious stuff
>>> help(myFunc.func_code)
Help on code object:
class code(object)
| code(argcount, nlocals, stacksize, flags, codestring, constants, names,
| varnames, filename, name, firstlineno, lnotab[, freevars[, cellvars]])
|
| Create a code object. Not for the faint of heart.
|