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()
Answer from Lauritz V. Thaulow on Stack OverflowI 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'
python - calling a function inside another function(nested) - Stack Overflow
Python Run Inner Function Within Module - Stack Overflow
Accessing inner functions in a class
How to call a function within a function from another function in Python? - Stack Overflow
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?
Something like the following presumably.
def foo():
def bar():
print("foo bar")
bar()
The function bar in this case is locally scoped to the function foo can cannot be called outside of that scope, unless it is returned from that scope to the outer scope.
>>> def foo():
... def bar():
... print("foo bar")
... bar()
... return bar
...
>>> bar = foo()
foo bar
>>> bar()
foo bar
It's the same thing you'd see if you wanted to access a variable locally scoped to a function outside of the function's scope.
def foo():
x = 42
print(x)
You would not expect to be able to access x except within the scope of the function foo.
You could use if statements within the outer function. This will allow you to only run the inner functions which need to be run. For example:
def outerFunction(parameter):
print("This is the outer function")
def innerFunction1():
print("This is the first inner function")
def innerFunction2():
print("This is the second inner function")
if parameter == "firstFunction":
innerFunction1()
else if parameter == "secondFunction":
innerFunction2()
outerFunction(secondFunction)
The output of the above code would be This is the second inner function
You can't, at least not directly.
I'm not sure why you would want to do that. If you want to be able to call func2() from outside func1(), simply define func2() at an appropriate outer scope.
One way that you could do it is to pass a parameter to func1() indicating that it should invoke func2():
def func1(call_func2=False):
def func2():
print("Hello!")
if call_func2:
return func2()
def func3():
func1(True)
but since that requires modification to the existing code, you might as well move func2() to the same scope as func1().
I don't recommend that you do this, however, with some indirection you can reach into the func1() function object and access it's code object. Then using that code object access the code object for the inner function func2(). Finally call it with exec():
>>> exec(func1.__code__.co_consts[1])
Hello!
To generalise, if you had multiple nested functions in an arbitrary order and you wanted to call a specific one by name:
from types import CodeType
for obj in func1.__code__.co_consts:
if isinstance(obj, CodeType) and obj.co_name == 'func2':
exec(obj)
Let's go into little deep and explore it :
You can do this via three methods :
First method:
Just return the nested function from main function so return will become the caller of nested function:
def func1():
def func2():
print("Hello!")
return func2()
def func3():
return func1()
func3()
output:
Hello!
Second method : Even you can pass argument directly to nested function:
Using Closure concept :
def func1():
def func2(x):
print("Hello {}".format(x))
return func2
closure=func1()
def func3():
return closure('bob')
func3()
Look above example , Main function is not accepting any parameter but nested function have one parameter so here i directly pass the argument to nested function.
Third method :
You can try this little hacky thing :
def func1():
def func2():
print("Hello")
return func2
def func3():
return func1()()
func3()