Search code examples
python-3.xmodulepackagedirectory-structure

How to distribute python classes into different source files without creating many modules?


I have a few related classes sitting in a package like this:

\cool
  \__init__.py
    class CoolObj: ...
    class CoolStr(CoolObj): ...
    class CoolName(CoolStr): ...
    class CoolSound(CoolObj): ...

And I use these classes like this:

import cool
cn = cool.CoolName()
...

This __init__.py file is getting too long. It would be nice if I could put each class in each of their own file like this:

\cool
    \__init__.py
    \cool_obj.py
        class CoolObj: ...
    \cool_str.py
        class CoolStr(CoolStr): ...
    \cool_name.py
        class CoolName(CoolStr): ...
    \cool_sound.py
        class CoolSound(CoolObj): ...

However, this way, these files becomes modules and I'd have to use them as below, which is a little verbose.

from cool import cool_obj, cool_str, cool_name, cool_sound
cn = cool_name.CoolName()

Is there anyway that can put source code in separate file while still be able to refer to them with concise syntax like I do now?

Better even, is there anything in python like partial class in C# that allows you to spread implementation of the same class in different files?


Solution

  • In your __init__.py you can do the imports to shorten how you use them elsewhere. So a line in __init__.py could be

    from cool_name import CoolName
    

    And later on you could do

    from cool import CoolName
    

    You may also want to look at __all__ as another way of solving this problem. You could import all sorts of stuff in the cool.__init__.py module and as long as you include an __all__ you can explicitly specify what objects will be exported.

    Regarding partial classes, I am almost sure Python does not support this kind of functionality through regular class definitions. You could hack it together by injecting different functions into a class at runtime, but that would certainly be messy. This answer takes a deeper look at that path.