Home > Blockchain >  Python: calling a child function using a string
Python: calling a child function using a string

Time:09-24

Does anyone know how to call a child function that belongs to a parent function using the dot operator, but where the child function's name is stored in a string variable.

def parent_function():
   # do something
   def child_function():
      # do something else

Now imagine I have a string called 'child_function'. Is there a way to do this:

method_name = 'child_function'
parent_function.method_name()

I understand that method_name is a string and so it is not callable. The syntax above is clearly wrong, but I wanted to know if there was a way to do this?

Thank you!

CodePudding user response:

As others have pointed out in comments there will need to be a little more setup to actually call an inner function, such as a parameter like this:

def parent_function(should_call=False):
   # do something
   def child_function():
      print("I'm the child")
   if should_call:
       child_function()

That being said, and to answer your specific question, you technically can call the inner function directly. I should note this is bad and you should not be doing this. You can access the inner function via the outer function's code object

exec(parent_function.__code__.co_consts[1])

CodePudding user response:

As opposed to many comments, you can actually access inner functions even if the outer function is not in the system memory anymore. This technique in python is called closure. To know more about closure, visit Programiz

Coming to your requirement, you need to call the nested method outside the nesting function.

What are we leveraging?

  1. Closure technique of python
  2. locals() method which returns all the local properties and methods inside an enclosing method.
  3. lambda x: x, A anonymous (Lambda) function
def parent_function():
    # do something

    def child_function():
        # do something else
        print("child_function got invoked")

    return {i: j for i, j in locals().items() if type(j) == type(lambda x: x)}
    # locals() returns all the properties and nested methods inside an enclosing method.
    # We are filtering out only the methods / funtions and not properties / variables

parent_function()["child_function"]()

The below is the output.

>>> child_function got invoked

Better Solution:

Instead of using nested methods, leverage the concept of classes provided by Python. Enclose the nested functions as methods inside a class.

CodePudding user response:

If you include global child_function in parent_function, then once you run parent_function, you can call child_function in the main program. It's not a very clean way of defining functions, though. If you want a function defined in the main program, then you should define it in the main program.

CodePudding user response:

Consider the following case:

def parent_function():
  a = 1

Can you access a from the global scope? No, because it is a local variable. It is only existent while parent_function runs, and forgotten after.

Now, in python, a function is stored in a variable just like any other value. child_function is a local variable just like a. Thus, it is in principle not possible to access it from outside parent_function.

Edit: unless you make it available to the outside somehow, e.g. by returning it. But then, still the name child_function is internal to parent_function.

Edit 2: You can get functions given by name (as string) by using the locals() and globals() dictionaries.

def my_function():
    print "my function!"

func_name = "my_function"
f = globals()[func_name]
f()
  • Related