0

I am refactoring a piece of Python 2 software. The code is currently in a single file, which contains 45 or so classes (and 2 lines outside of a class to bootstrap the application).

I'd like to have one class per file, with ideally files from related classes grouped in directories.

I typically like to write my Python imports as such:

from zoo.dog_classes.beagle_class import BeagleClass
from zoo.dog_classes.dalmatian_class import DalmatianClass

so that it is clear which modules are imported in the class, and that their name is as short as possible.

For this software, the logic is quite complex though, with classes referring to one another commonly in class methods, resulting in numerous circular imports, which rules out this approach.

I do not want to import modules in functions, as this is horrible for readability and code gets repeated everywhere.

It seems like my only option is to write imports in such a fashion:

import zoo.dog_classes.beagle_class

and later, when I need the class:

b = zoo.dog_classes.beagle_class.BeagleClass()

This is however extremely verbose and painful to write.

How should I deal with my imports?

bitgarden
  • 10,461
  • 3
  • 18
  • 25
  • You should probably think about getting rid of "one class per module" approach. First, it implicitly forces you to create larger classes instead of splitting the functionality (and making pure functions where necessary). Second, you are not using that additional level of abstraction modules provide (which would probably decrease the total amount of imports substantially). – fjarri Sep 26 '13 at 07:40
  • The classes are really large. I'm aware this is far from ideal, but I'd like to refactor the software through several steps- the first of which would be to break it down in separate files. – bitgarden Sep 26 '13 at 21:52

1 Answers1

1
import zoo.dog_classes.beagle_class as beagle

b = beagle.BeagleClass()
William Gaul
  • 3,181
  • 2
  • 15
  • 21
  • Currently the code is all in the same file, and therefore there are many calls to BeagleClass and friends without any module name prepended. I'd like to keep it that way if possible; i.e. be able to write plainly BeagleClass() anywhere in the code base. – bitgarden Sep 26 '13 at 07:29
  • Hmm but you're going to be splitting up the code...? This is about as simple as you can get without resorting to `from` syntax, but like you said that will cause problems as well. – William Gaul Sep 26 '13 at 07:33
  • Right - this is a pretty complex piece of code (essentially a graphical desktop manager + UI toolkit), and all the classes are named distinctly enough and represent distinct enough concepts for their name to be self-describing, but they are heavily interdependent :( – bitgarden Sep 26 '13 at 07:35
  • Well I found this thing if it's of any help: http://stackoverflow.com/questions/894864/circular-dependency-in-python. Apparently you can fix circular dependencies by moving one of the imports to the end of the module. That still doesn't make it any less complex though, I'd really try to pen-and-paper diagram it out and see if you can reduce the dependencies. – William Gaul Sep 26 '13 at 07:37