1

I think that this is a quite basic question, but I wasn't able to find anything. Sorry if this happen to be a duplicate.

I have a file with some functions defined, let's call this file main_functions.py.

In this file I rely on a function, which we can call foo(). For instance, in the file main_functions.py we can have something like this:

def bar():
    return foo()

foo() is definend in another file, called secondary_functions.py

def foo():
    return 1

Now, in my main script, I would like to import a file where I can define foo(), and then do something like:

from secondary_functions import *    # Here I define foo()
from main_functions import *  

bar()

If I do so, the function inside main_functions is not able to find the definitions that are present in secondary_functions, and I will get an error like:

NameError: name 'foo' is not defined

It is very important for me to solve this problem.

My aim is to be able to have different files called secondary_functions1.py, secondary_functions2.py, eccetera, definitions of foo().

And, to solve the problem, I don't want to change everytime the file that depend on these definitions, for instance inserting everytime something like import secondary_functionsX.py, which would solve the problem. I would like to change only the main script.

spy95
  • 131
  • 8

3 Answers3

1

After the import statements, variables like pippo have become global variables in the scope of the main program. But global variables are not inherited by modules that get imported. Modules are supposed to be able to stand on their own as self-contained units, that can be imported by any program; imagine what could go wrong if they started using variables from whatever imports them...

Thus, the only way to do this is explicitly ‘giving’ the values to your module, for instance as additional function arguments. You could put everything that’s in main_functions.py in a Class, and then have your main script give it the desired global variables as arguments of its init construction function, so it can store them for usage by bar() and other methods.

Jim Danner
  • 535
  • 2
  • 13
  • Thanks! I didn't want to use classes but using them I actually solved my problem. Bu I still don't know if there is a way to solve the problem without using classes. I don't close the question because I am pretty curious to see if there is a way to overcome the problem without recurring to a class ;) – spy95 Dec 16 '18 at 11:59
1

The foo name is imported in main.py. foo is not available in the main_functions.py module, because you have not imported it in that module. See Namespaces with Module Imports for more on why it works this way.

One way to do what you want is to supply foo as an argument to bar(). Example:

main.py:

from secondary_functions import foo
from main_functions import bar 

bar(foo)

main_functions.py:

def bar(foo):
    return foo()

secondary_functions.py:

def foo():
    return 1
mzjn
  • 48,958
  • 13
  • 128
  • 248
0

It seems that the problem isn't calling the files correctly it's that you're not calling pippo correctly, if pippo is a global variable then i don't see why it's not working. the only way i can think of solving this is by saying file.pippo

and if you're going to have multiple files with a variable called pippo then it's best not to make them global and call then individually like i just showed you.

another thing that could be the problem is if you are defining pippo inside a function, which then makes it a local variable to that function only.

And the last problem i can think of is if you're using them in main_functions and they haven't been defined in main_functions and you're not importing the files into main_functions i.e # in main_functions.py
import secondary_functions

then i don't think main_functions will be able to find the function and variable without making them arguments for the function you're using them in. or again you can do something like file.pippo

Aguy
  • 169
  • 11
  • Sorry, I edited a little bit the question and now pippo is gone. Btw, I don't want to import secondary_functions in main_functions. I want to choose the secondary_functions uniquely in the main script. So I cannot do secondary_functions.foo anyway... – spy95 Dec 16 '18 at 10:07
  • I see you're problem. And again the only way i can think of fixing this is by calling it in bar() like so "return secondary_functions.foo()" or again putting foo as an argument for the function bar. And my last idea which i don't think will work is by making a class that has the function foo() and calling it from the class – Aguy Dec 16 '18 at 10:15