How to call nested function in python

I have a method that i have broken into smaller nested functions to break up the code base:

def foo(x,y):
    def do_this(x,y):
        pass
    def do_that(x,y):
        pass
    do_this(x,y)
    do_that(x,y)
    return

Is there a way to run one of the nested functions by itself. eg:

foo.do_this(x,y)

EDIT:

I am trying to setup caching on a web server i have built using pyramid_breaker

def getThis(request):
    def invalidate_data(getData,'long_term',search_term):
         region_invalidate(getData,'long_term',search_term)
    @cached_region('long_term')
    def getData(search_term):
         return response
    search_term = request.matchdict['searchterm']
    return getData(search_term)

This is my understanding may not be accurate:

Now the reason i have this is that the namespace used by the decorator to create the cache key is genereated from the function and the arguements. You can't therefore just put the decorator on getThis as the request variable is unique-ish and the cache is useless. So i created the inner function which has repeatable args (search_term).

However to invalidate the cache (ie refresh), the invalidation function requires scope to know of the 'getData' function so also needs to be nested. Therefore i need to call the nested function. You wonderful people have made it clear its not possible so is someone able to explain how i might do it with a different structure?

asked Jun 22, 2012 at 10:41

user1474424user1474424

6571 gold badge5 silver badges18 bronze badges

4

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()

answered Jun 22, 2012 at 10:44

6

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'

answered Oct 15, 2015 at 15:09

Jens TimmermanJens Timmerman

8,6871 gold badge39 silver badges46 bronze badges

4

There is, you have to make them as an attribute of the function object. But this will work only after the first call of foo.

def foo(x,y):
    def do_this(x,y):
        pass
    def do_that(x,y):
        pass
    do_this(x,y)
    do_that(x,y)
    foo.do_this = do_this
    foo.do_that = do_that
    return

>>> foo.do_this(1, 2)
AttributeError: 'function' object has no attribute 'do_this'
>>> foo(1, 2)
>>> foo.do_this(1, 2)
>>>

answered Jun 22, 2012 at 10:52

mutantaculemutantacule

6,7031 gold badge26 silver badges39 bronze badges

No (apart from poking around in closure objects, which is complete overkill here). If you need that, use a class.

class foo(object):
    def do_this(self, x, y):
       ...
    def do_that(self, x, y):
       ...
    def do_other_stuff(self, x, y):
       # or __call__, possibly

Or just put those functions in the outer scope, since you're passing everything as arguments anyway:

def foo(x, y):
    do_this(x, y)
    do_that(x, y)

def do_this(x, y):
    ...

def do_that(x, y):
    ...

answered Jun 22, 2012 at 10:44

Cat Plus PlusCat Plus Plus

122k26 gold badges195 silver badges222 bronze badges

No, there is not. Since you may access variables in an outer scope from within a nested function:

def foo(x,y):
    def do_this(z):
        print(x,y,z)
    # ...

there is no way to call do_this while providing a binding for x and y.

If you must call do_this from elsewhere, simply make it a top level function at the same level as foo.

answered Jun 22, 2012 at 10:44

Greg HewgillGreg Hewgill

908k177 gold badges1131 silver badges1267 bronze badges

1

You can try this way:

def a(x, y):
    name = 'Michael'
    a.name = name

    a.z = z = x * y
    #a.z = z

def b():
    def give_me_price(f,g):
        price = f * g
        return price

    def two(j,k):
        surname = 'Jordan' # without return surname give None

    # two = two('arg1', 'arg2')
    # b.blabla = two

    one = give_me_price(5, 10)
    b.halabala = one

    print(a.name) # ;)

x = 20
y = 30

a(x,y) # IMPORTANT! first you must run function
print(a.z)
print(a.name * 5)

print('-'*12)
b() # IMPORTANT! first you must run function
print('price is: ' + str(b.give_me_price(5, 25)))
# print(b.blabla)

answered Aug 10, 2018 at 8:14

How to call nested function in python

This is how I did it.

CODE

def getMessage(a="", b="", c=""):
    def getErrorMessage(aa, bb):
        return "Error Message with/without params: {}{}".format(aa, bb)

    def getSuccessMessage(bb, cc):
        return "Success Message with/without params:  {}{}".format(bb, cc)

    def getWarningMessage(aa, cc):
        return "Warning Message with/without params:  {}{}".format(aa, cc)

    return {
        "getErrorMessage": getErrorMessage(a, b),
        "getSuccessMessage": getSuccessMessage(b, c),
        "getWarningMessage": getWarningMessage(a, c),
    }


a = "hello"
b = " World"
c = "!"
print(getMessage(a, b)["getErrorMessage"])
print(getMessage(b=b, c=c)["getSuccessMessage"])
print(getMessage(a=a, c=c)["getWarningMessage"])
print(getMessage(c=c)["getWarningMessage"])

OUTPUT

Error Message with/without params: hello World
Success Message with/without params:   World!
Warning Message with/without params:  hello!
Warning Message with/without params:  !

answered Jan 28, 2021 at 16:44

Anurag PAnurag P

3173 silver badges10 bronze badges

How do you call nested functions?

Approach:.
Write one function inside another function..
Make a call to the inner function in the return statement of the outer function..
Call it fun(a)(b) where a is parameter to outer and b is to the inner function..
Finally return the combined output from the nested function..

How do you call nest inner 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 call one function inside another function in Python?

The Fucntion1 Calls Function2 now the State of the Function1 is stored stack and execution of Function 1 will be continued when Function 2 returns. Consider the below Example of the function call. The Function SumOfSquares function calls the Function Square which returns the square of the number.

Can you have nested functions in Python?

Inner functions, also known as nested functions, are functions that you define inside other functions. In Python, this kind of function has direct access to variables and names defined in the enclosing function. Inner functions have many uses, most notably as closure factories and decorator functions.