Python导入语句根据__init__.py中的位置不起作用

时间:2018-11-06 17:42:09

标签: python

让我们采用这样的文件夹结构:

project_root
│   start.py
└───Application
    └───ViewModels
        │   __init__.py
        │   MagnifierWindowViewModel.py
        │   MainViewModel.py
        │   MainWindowViewModel.py
        │   PlotterWindowViewModel.py

这些是文件的内容:

  

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

使用这种结构,我会收到此错误:

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

但是,如果我将最后一行放在Application\ViewModels\__init__.py中,则该应用程序运行正常。为什么会这样?

我拥有这个Application\ViewModels\__init__.py的原因是我可以写

from Application.ViewModels import MagnifierWindowViewModel

代替

from Application.ViewModels.MagnifierWindowViewModel import MagnifierWindowViewModel

1 个答案:

答案 0 :(得分:1)

您已经将每个类卡在了与该类完全相同的模块中。出于您在这里看到的原因,这是一个非常不好的主意:将类和模块混合在一起太容易了。

您的MainViewModel.py执行导入时:

from Application.ViewModels import MagnifierWindowViewModel, MainWindowViewModel, PlotterWindowViewModel

导入的内容取决于已执行的Application\ViewModels\__init__.py数量。如果此行尚未执行:

from Application.ViewModels.MainWindowViewModel import *

然后在MainViewModel.py中导入将导入MainWindowViewModel模块。如果执行了import * ,则它将在模块内部定义的MainWindowViewModel类下对MainWindowViewModel模块进行阴影处理,因此MainViewModel.py中的import会被导入MainWindowViewModel类。