Python: How to refactor circular imports
python, refactoring
Solution
Without seeing code, what would make the most sense is to merge the two files. If they are that closely intertwined, you could probably put them together without anything really oddly out of place.
Problem
I've got a thing that you can do `engine.setState(<state class>)` and it will instantiate the class type you give it and start running on the new state. In `SelectFileState` there is a button to go to `NewFileState`, and on `NewFileState`, there is a button to go back to `SelectFileState`. Now, at the beginning of `SelectFileState`, I'm importing `NewFileState` (So I can later in the class do `engine.setState(NewFileState)`. At the beginning of `NewFileState`, I'm also importing `SelectFileState` (So I can later go back to `SelectFileState`). However, this creates a circular import, as described in some other posts. Some say that circular imports are indicators bad design, and should be refactored.. I know that I can just fix this problem by importing `SelectFileState` right before I need to use it, but I'd rather do things the right way and refactor it. Now I'm wondering though.. How would you refactor that out? Thanks. Edit: Pydsigner suggests that I merge the two files into one, as they are both very related to each other. However, I cannot put EVERY state that has a circular dependency into one file, so there's got to be a better method for that. Any ideas? 2Edit: I'm circumventing this problem for now by not using the `from x import y` syntax, and instead just doing `import x`. This is not a preferable solution, and I'd like to know the "Pythonic" way to fix this kind of thing. Just merging files together can't be the fix forever. The code: SelectFileState ``` from states.state import State from states.newfilestate import NewFileState from elements.poster import Poster from elements.label import Label from elements.button import Button from elements.trifader import TriFader import glob import os class SelectFileState(State): def __init__(self, engine): super().__init__(engine) def create(self): self.engine.createElement((0, 0), Poster(self.engine.getImage('gui_loadsave')), 1) self.engine.createElement((168, 30), Label("Load a game", 40), 2) self.engine.createElement((400, 470), Button("New save", code=self.engine.createElement, args=((0, 0), TriFader(NewFileState, False), -240)), 3) ycounter = 150 globs = glob.glob("save\\*.mcw") for file in globs: self.engine.createElement((200, ycounter), Button(os.path.basename(file)[:-4]), 2) ycounter += 50 ``` NewFileState ``` from states.state import State from states.selectfilestate import SelectFileState from elements.poster import Poster from elements.label import Label from elements.button import Button from elements.inputbox import InputBox from elements.trifader import TriFader class NewFileState(State): def __init__(self, engine): super().__init__(engine) def create(self): self.engine.createElement((0, 0), Poster(self.engine.getImage('gui_loadsave')), 1) self.engine.createElement((135, 30), Label("Make a new save", 40), 2) self.lvlname = self.engine.createElement((180, 212), InputBox(length=25, text="World name"), 2) self.engine.createElement((200, 240), Button(text="Ok", code=self.createSave, args=()), 2) def createSave(self): open("save\\" + self.lvlname.getText() + ".mcw", 'w') self.engine.createElement((0, 0), TriFader(SelectFileState), -240) ```