0

Let's say i have a really long script.(1000+ lines long, in my case) so i split it into sepperate files:

main.py #the file i execute
foo1.py #a file my main.py imports
foo2.py #a file imported by foo1.py

(note: main.py imports several files, not just the one) Foo1.py holds Tkinter, and things related to it, while Foo2.py holds a huge object class with functions related to said class.

My problem is as follows:

  • Foo1 imports Foo2
  • Foo2 runs a function that calls another function from Foo1
  • Foo2 raises a 'global name ' is not defined' error

And also i can't import the function into Foo2, because Foo1 already has it and that raises an import error.

Kieee
  • 126
  • 2
  • 15
  • 1
    so you have [circular importing](http://stackoverflow.com/questions/22187279/python-circular-importing)? if you only use code from the other module in functions (not at module level) simply importing the module `import foo1` instead of importing names from it `from foo1 import *` will usually fix the issue. – Tadhg McDonald-Jensen Mar 06 '17 at 22:15
  • @Tadhg I guess so. But i have to have the function from Foo1, and i can't move it to Foo2. – Kieee Mar 06 '17 at 22:19
  • @Tadhg I use `import folder.foo2 as foo2` – Kieee Mar 06 '17 at 22:21
  • clarifying questions: 1. is code from one module only uses declarations from the other modules _inside functions_ (not at module level) ? 2. are you currently using `from .. import ...` syntax? circular imports are do-able but those are two caveats that prevent it from working. – Tadhg McDonald-Jensen Mar 06 '17 at 22:24
  • @Tadhg not sure what you mean by 'only uses declarations'. Both of the files execute code, and define functions, classes, and variables. And the only ` from ...` i use is Tkinter and ttk – Kieee Mar 06 '17 at 22:29
  • @Tadhg If you mean do the `function_calls()` from Foo1 exist out side of the functions of Foo2, the answer is no. – Kieee Mar 06 '17 at 22:32
  • um... then are you missing an import statement in foo2? without using `from import` I don't see why you'd be getting "Foo2 raises a 'global name ' is not defined' error" – Tadhg McDonald-Jensen Mar 06 '17 at 22:37
  • @Tadhg i get an import error if i try and import Foo1 into Foo2. I assume its because I imported Foo2 into Foo1. – Kieee Mar 06 '17 at 22:39
  • @Tadhg I found the problem in an unexpected place.. foo1 and foo2 are in a subdirectory of main.py called 'data' and from main i was importing data.foo1 - however from foo2 i was also using `import data.foo1`, and it was tossing an error that i assumex was because of the import round-robin, but it was because i had to use `import foo1` instead of `data.foo1` – Kieee Mar 06 '17 at 22:56
  • @Tadhg i would of never checked that if you didn't mention your confusion on why it wasn't working. – Kieee Mar 06 '17 at 22:57
  • @Tadhg Now i am at a point were i have to use `from ... Import Foo1` because the file in queation is located two folders below Foo1 – Kieee Mar 06 '17 at 23:28

1 Answers1

1

When two modules import each other there are a few things you need to keep in mind so everything is defined before it is needed.

First lets consider the mechanic of importing:

  • when a module is imported for the first time an entry is added to sys.modules and the defining file starts executing (pausing the execution of the import-er)
  • subsequent imports will simply use the entry in sys.modules - whether or not the file finished executing

So lets say module A is loaded first, imports module B which then imports module A, when this happens execution is as follows:

  1. A is imported from something else for first time, A is added to sys.modules
  2. A is executed up to importing B
  3. B is added to sys.modules
  4. B is executed:
    • when it imports A the partially loaded module is used from sys.modules
    • B runs completely before resuming
  5. A resumes executing, having access to the complete module B

*1 so from A import x can only work if x is defined in A before import B, just using import A will give you the module object which is updated as the file executes, so while it may not have all the definitions right after import it will when the file has a chance to finish executing.


So the simplest way of solving this is to first not rely on the import for the execution of the module - meaning all the uses of the circular import is within def blocks that are not called from the module level of execution.

Tadhg McDonald-Jensen
  • 20,699
  • 5
  • 35
  • 59
  • with packages `from data import foo2` would still be importing the live-updating module object so it would work the same way. – Tadhg McDonald-Jensen Mar 07 '17 at 14:06
  • What about if i have to use a relative import? Like import `from` two levels up? This i did try, and it failed. I did confirm that the folder i was importing from was correct. – Kieee Mar 07 '17 at 14:28
  • the important part is that you are importing a **module** _instead of_ **names** inside the module, so `from .. import package` is fine but `from ..package import var` would only work if `var` was defined before the active module was loaded. (which it won't if you put all the imports at top of files) – Tadhg McDonald-Jensen Mar 07 '17 at 19:18
  • btw, if you are just trying to split up a file that is too long into multiple files why is part of that going into levels above in packages? that seems a bit of a jump for one run of refactoring. – Tadhg McDonald-Jensen Mar 07 '17 at 19:20
  • I have the scripts organised into folders, like this: `data\\user\\test123\\settings.py` thats why. My project is a game. – Kieee Mar 07 '17 at 19:44