Reputation: 67
Let's take a folder structure like this:
project_root
│ start.py
└───Application
└───ViewModels
│ __init__.py
│ MagnifierWindowViewModel.py
│ MainViewModel.py
│ MainWindowViewModel.py
│ PlotterWindowViewModel.py
These are the contents of the files:
start.py
from Application.ViewModels import MainViewModel
if __name__ == "__main__":
mainViewModel = MainViewModel()
Application\ViewModels\__init__.py
from Application.ViewModels.PlotterWindowViewModel import *
from Application.ViewModels.MagnifierWindowViewModel import *
from Application.ViewModels.MainViewModel import *
from Application.ViewModels.MainWindowViewModel import *
Application\ViewModels\MagnifierWindowViewModel.py
class MagnifierWindowViewModel(object):
def __init__(self):
pass
Application\ViewModels\MainViewModel.py
from Application.ViewModels import MagnifierWindowViewModel, MainWindowViewModel, PlotterWindowViewModel
class MainViewModel(object):
def __init__(self):
self.mainWindowVM = MainWindowViewModel()
self.magnifierWindowVM = MagnifierWindowViewModel()
self.plotterWindowVM = PlotterWindowViewModel()
Application\ViewModels\MainWindowViewModel.py
class MainWindowViewModel(object):
def __init__(self):
pass
Application\ViewModels\PlotterWindowViewModel.py
class PlotterWindowViewModel(object):
def __init__(self):
pass
With this structure, I get this error:
Traceback (most recent call last):
File "project_root/start.py", line 4, in <module>
mainViewModel = MainViewModel()
File "project_root/Application/ViewModels/MainViewModel.py", line 5, in __init__
self.mainWindowVM = MainWindowViewModel()
TypeError: 'module' object is not callable
But if I put the last line in Application\ViewModels\__init__.py
first, the application runs just fine. Why is that?
The reason I have this Application\ViewModels\__init__.py
is so that I can write
from Application.ViewModels import MagnifierWindowViewModel
instead of
from Application.ViewModels.MagnifierWindowViewModel import MagnifierWindowViewModel
Upvotes: 2
Views: 291
Reputation: 280973
You've stuck every class in its own module named the exact same thing as the class. That's a really bad idea for the reasons you're seeing here: it is way too easy to get the class and the module mixed up.
When your MainViewModel.py
performs its imports:
from Application.ViewModels import MagnifierWindowViewModel, MainWindowViewModel, PlotterWindowViewModel
what gets imported depends on how much of Application\ViewModels\__init__.py
has executed. If this line has not executed:
from Application.ViewModels.MainWindowViewModel import *
then the import in MainViewModel.py
imports the MainWindowViewModel
module. If the import *
has executed, then it shadows the MainWindowViewModel
module with the MainWindowViewModel
class defined inside the module, so the import in MainViewModel.py
imports the MainWindowViewModel
class.
Upvotes: 1