1

Lets say that I have a script, test.py, that has a function that it within another function:

 x = 3
 def function_1(x):
     ...
     y = x + 7

     def function_2():
        return value

Now I want to use both function_1 and function_2 in another script. How do I do that?

I've tried this:

import test
from test import function_1
from function_1 import function_2

I basically just get an error saying No module named function_1. It does import function_1 and I can use it, but not function_2. I can't just make function_1 a class (it needs a parameter). How can I fix this? Can I somehow use _main_ to replace function_1? Could I then import just function_2?

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
gwydion93
  • 1,681
  • 3
  • 28
  • 59
  • Possible duplicate of [Call Nested Function in Python](https://stackoverflow.com/questions/11154634/call-nested-function-in-python) – kabanus Sep 25 '18 at 18:43
  • Originally, they were not nested. But I was trying to runt the full script (everything within function_1) within another script. The easiest way I could figure out how to do that was make the entire script a function, import the script, and call the function inside the other script. So, to clarify, 1) How can I call my full script(`test.py`) inside another script and, 2) then call just `function_2`? I think if I can do #1, I can do #2. – gwydion93 Sep 25 '18 at 18:44
  • When you import the entire script is run. You can just define `function_2` in the global namespace, and then call it in the script somewhere. – kabanus Sep 25 '18 at 18:44
  • I've updated my answer in response to your update. I hope it helps. – Mad Physicist Sep 25 '18 at 18:51

1 Answers1

2

A nested function function_2 is an object in the local namespace of the outer function. It doesn't even exist as a function when function_1 is not running.

Normally, a nested function either performs a private computation for the outer function, or gets returned in some form or another. In the latter case, you can run function_1 to get a reference to function_2.

Any object that you want to import should be in the global namespace, or at least directly referenceable from it. A better design would be

x = 3

def function_1(x):
    y = x + 7
    # Do some stuff, including using function_2
    return y

def function_2(value):
    # Do some stuff
    return value

And keep in mind that defining a function is not the same as running it. As a corollary, the x inside function_1 is not the same as the x that you set to 3 at the module level.

Update for your update

You absolutely can make function_1 into a class, and make function_2 a method of it:

class function_1:
    def __call__(self, x):
        y = x + 7
        value = self.function_2(y)
        return y, value

    @staticmethod
    def function_2(value):
        return value

In this case you could do the following in your other script:

from test import function_1

f1 = function_1()
# Call it:
f1(7)
# Call function_2:
function_1.function_2('blah')
# Or alternatively:
f1.function_2('foo')
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264