1

I have a python application that has grown in size and complexity. I now have 2 folders - one that contain some utility classes and another that contains some other classes. It's quite a long list in each and the classes are referenced all over the place.

MyApp Folder
  main_app.py
  -- states
      - Class1.py
      - Class2.py
  -- util
      - Util1.py
      - Util2.py

In main_ap.py is there a way I can just do import states and then reference any classes within that folder as states.Class1? I'd do the same for the util folder but the difference there is some of these classes reference each other.

I've tried __init__.py and some other things but i'm a legacy C++/C developer and relatively new to Python and i think this is handled much differently.

martineau
  • 119,623
  • 25
  • 170
  • 301
  • What does "I've tried init.py" mean? Where is the *code* that you tried, and how did it fail? – Scott Hunter Jan 07 '22 at 20:17
  • 1
    `__init__.py` is indeed the way to do this. Inside of that file you can do for example `from Class1 import XYZ` to pull `XYZ` into the `states` package scope. That would allow you to use it as either `states.Class1.XYZ` or simply `states.XYZ` – 0x5453 Jan 07 '22 at 20:18
  • This structure looks a lot more Java-like than how things work in Python. You don't need to put each class in a file named after the class, and doing so is usually a bad idea due to issues with name clashes and circular imports. Also, if those "utility classes" are just ways to group related utility functions and not actually something you would ever want to instantiate, then that's a job for a module, not a class. – user2357112 Jan 07 '22 at 21:05

3 Answers3

0

If states.__init__.py does from .Class1 import * and from .Class2 import *, then main.py can do import states and then states.SomeClassFromClass1Module

Eldamir
  • 9,888
  • 6
  • 52
  • 73
0

So __init__.py is a file that is executed the first time when you access something inside that package.

Saying that, import states is a way to execute content of states/__init__.py

# states/__init__.py

from states.Class1 import MyClass
# Or with relative path
from .Class2 import MyClass as MyClass2
# main_app.py

import states
states.MyClass() # It works

from states import MyClass2
MyClass2() # It works too.

In case you decide to use asterisk import (as Eldamir stated) you can be interested in __all__ keyword.

kosciej16
  • 6,294
  • 1
  • 18
  • 29
0

define a __init__.py file and then import the classes you want in the __init__.py file eg from class1 import class11 then at last define __all__ method and write all the class name which you want to be used as states.class11 as __all__ = ['class11', 'class12',.. ]

sahasrara62
  • 10,069
  • 3
  • 29
  • 44