-1

I want to have two or more python files that can call each other's functions, as if they were part of the same file. Tested importing each other in both files but has strange results and I don't think this is the right way to do it. Any ideas on how to do this?

Thanks

holmeswatson
  • 969
  • 3
  • 14
  • 39
  • 9
    Can you please provide some concrete examples of your project structure, what you are trying to `import` in to what, and the contents of the files you are trying to work with? – Silas Ray Feb 21 '13 at 18:06
  • 1
    What "strange" results did you have? – martineau Feb 21 '13 at 18:17
  • sorry, i have a games loader that needs to load up a pygame GUI from another file if that option is checked, then the user can click a button on the GUI (or hardware if GUI not wanted) and that will cause the games loader to load a particular game which the user interfaces with through the GUI (or hardware), so they seem to need to import each other to use each others functions? – holmeswatson Feb 21 '13 at 18:18
  • a loop that cycled twice through the two files linked together, then finished... – holmeswatson Feb 21 '13 at 18:19
  • 1
    You should probably have a GUI layer, a loader, and then a sequence of objects that encapsulate the game data and can be loaded in and out of the GUI in a loosely coupled way (write the games to work with the GUI, not the GUI to work with the games). We can't really be any more concrete without some actual code and exceptions to go off of though. – Silas Ray Feb 21 '13 at 18:21
  • `import`s that aren't at the module level (i.e. that are inside functions or methods) can cause problems if you have circular references. A way to resolve it is to move them up to the top level. – martineau Feb 21 '13 at 18:25
  • 1
    The answer(s) to the question [Pythonic way to resolve circular import statements?](http://stackoverflow.com/questions/5748946/pythonic-way-to-resolve-circular-import-statements) may help. – martineau Feb 21 '13 at 18:29
  • `import`s at the module level can cause issues perfectly fine on their own. For example, `A` imports `B` imports `A`, `B` tries to call `A.foo()` directly or indirectly from module scope (so it tries to execute at module load time), you get an `AttributeError` on `A`. – Silas Ray Feb 21 '13 at 18:29
  • as pointed out by Sr2222, you have an architectural problem more than a Python problem. I would suggest you to read about "hexagonal architecture", don't mind the long article's details, but notice the overall idea, it has been very very useful to me: http://alistair.cockburn.us/Hexagonal+architecture – heltonbiker Feb 21 '13 at 18:30
  • @sr2222 "write the games to work with the GUI" - Thats how I want to do it, but i feel that would require me to import the GUI into the game files, but the games files are chosen by the GUI, so it must already be up before the game is, sorry I know this is vague – holmeswatson Feb 21 '13 at 18:37
  • They have to work together, but not necessarily explicitly on both ends. If you have some sort of `Subprogram` object that exposes an interface that lets you connect input and output streams to it, then a GUI runner that has some sort of `load()` method that hooks up inputs and outputs (stdin, screen buffer, etc) to any object that has the expected interface, you can implement anything you want on either side of the interface and neither side has to know anything about the other's implementation details. – Silas Ray Feb 21 '13 at 18:42
  • @sr2222 sort of like message passing using global variables? – holmeswatson Feb 21 '13 at 18:46
  • 1
    Most decidedly not global variables. You should probably read up on OOD/OOP. It is like global message passing in that components communicate through abstracted interfaces and hide implementation details from eachother, but it is coming from a different design paradigm that explicitly avoids the concept of dumping things in to global namespaces in favor of easier to identify, document, and debug explicit, limited interfaces. – Silas Ray Feb 21 '13 at 18:53
  • +1 to @sr2222. The key idea here is interfaces. One side can use any object that implements a given interface. The other side implements that interface. So, they can work together, without either one depending on the other. They just both depend on the _interface_. (And in Python, this doesn't even have to be explicit; the interface can just be "has a `draw(canvas)` method". But if you want to do it via an "Abstract Base Class" or "Protocol", to get something more explicit and Java/ObjC/whatever-like, they both just import the interface module.) – abarnert Feb 21 '13 at 19:30

2 Answers2

2

import is the right way to do it. You are probably running in to circular import errors or something similar, which should be fixed by reorganizing your code.

Silas Ray
  • 25,682
  • 5
  • 48
  • 63
  • no sure on a good way to reorganise my code. i have three files, an application loader that can load a GUI if necessary and can load different games files depending on what is clicked on the GUI (or hardware) and those games are interacted with through the GUI, so they need to be able to call each others functions? – holmeswatson Feb 21 '13 at 18:14
  • This is too vague. Can you please modify your initial question with your code or a link to your code repo or something? – Silas Ray Feb 21 '13 at 18:18
  • sorry, i know its vague, but the files are rather long and messy. the problems im having is with getting the files to use each other (or how to reorganise what file calls what) not the actual contents of the files – holmeswatson Feb 21 '13 at 18:21
  • Well, it's pretty hard to reorganize code we can't see... if the code is long, sign up for git or use pastebin or something. – Silas Ray Feb 21 '13 at 18:22
  • 1
    As a rule of architecture layering, files should not reference each other arbitrarily: top-level files should import lower level files, but lower level files should not reference higher-level files. That way, you have one-directional dependencies that constitute the structure of a layered architecture (a very wise although simple way to implement software system, small or large). – heltonbiker Feb 21 '13 at 18:33
0

Let's say that I have a function called test in TestFile.py

If I want to import test in a different .py file then I would do

from TestFile import test

that would then allow me to use the test function in my new .py file.

Wesley Bowman
  • 1,366
  • 16
  • 35