如何在Python的子目录下加载所有模块?

时间:2016-03-14 15:54:50

标签: python package python-import python-module

我将常用的模块放在子目录lib/中,并期望通过以下方式将所有模块加载到main.py中:(请参阅Python: how to import from all modules in dir?

from lib import *

但遇到问题TypeError: 'module' object is not callable。更具体地说,在main.py

#!/usr/bin/env python

from lib import * # cause: TypeError: 'module' object is not callable
#from lib.DominatingSets import *   # it works

dominatingSets = DominatingSets()

完整的异常追溯:

$ python main.py 
Traceback (most recent call last):
  File "main.py", line 6, in <module>
    dominatingSets = DominatingSets()
TypeError: 'module' object is not callable

树状格式的目录。

$ tree -P '*.py' .
.
├── __init__.py
├── lib
│   ├── AnalyzeGraph.py
│   ├── AutoVivification.py
│   ├── DominatingSets.py
│   ├── __init__.py
│   ├── Output.py
│   ├── PlotGraph.py
│   ├── ProcessDatasets.py
│   └── ReadGTFS.py
├── main.py

lib/__init__.py的内容如下。 (参考Loading all modules in a folder in Python

from os.path import dirname, basename, isfile
import glob
modules = glob.glob(dirname(__file__)+"/*.py")
__all__ = [ basename(f)[:-3] for f in modules if isfile(f) and not basename(f).startswith('__')] # exclude __init__.py

3 个答案:

答案 0 :(得分:2)

这种混淆部分是因为您的模块名称与要从中加载的类的名称相同。 (至少,这就是让它更加混乱的原因。)你的代码确实正确地加载了你的类所在的模块。但是,它并没有从这些模块中加载类,这就是你真正想要做的事情。 / p>

由于您的班级DominatingSets位于模块lib.DominatingSets中,因此其根目录的完整路径为lib.DominatingSets.DominatingSets

from lib import *

在你的情况下将做与

相同的事情
from lib import DominatingSets
from lib import AnalyzeGraph
# ...

然而,

from lib import DominatingSets

相当于

import lib.DominatingSets
DominatingSets = lib.DominatingSets

但是lib.DominatingSets模块lib/DominatingSets.py),而不是您想要的课程。

from lib.DominatingSets import DominatingSets

相当于

import lib.DominatingSets
DominatingSets = lib.DominatingSets.DominatingSets

这就是它的工作原理:这是您要导入名称DominatingSets的类。

如果要让from lib import *导入子模块中的所有类,则需要将这些类导入lib模块。例如,在lib/__init__.py

from DominatingSets import *
from AnalyzeGraph import *
# ...

在进行更改时,我建议(正如其他人一样)使用普通的Python命名约定,并将模块名称设置为小写:将DominatingSets.py更改为dominatingsets.py。然后这段代码将成为

from dominatingsets import *
from analyzegraph import *
# ...

答案 1 :(得分:2)

看看你的Traceback,我认为你的问题可能就在这里:

首先,让我们看一个例子:

import datetime
d = datetime(2005, 23, 12)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'module' object is not callable

基本上,我们刚刚导入了整个datetime模块,我们试图将其称为模块中的类对象。我们现在做:

k = datetime.datetime(2005, 12, 22)
print k
2005-12-22 00:00:00

这次没问题,因为我们在datetime模块中引用了datetime对象类型

如果我们这样做:

from datetime import datetime
datetime
<type 'datetime.datetime'>

我们再次到达所需的对象,因为我们正在datetime模块中导入datetime类。 另外,使用*

from datetime import *
d = datetime(2005, 3, 12)
当您导入datetime模块中的所有类时,

也将起作用。

你的代码说:

from lib import * # This imports all MODULES within lib, not the classes
#from lib.DominatingSets import *   # it works because you import the classes within the DominatingSets Module

您可以使用from lib.DominatingSets import DominatingSets来解决您的问题,或者如果您坚持from lib import *,请将您的代码更改为dominatingsets = DominatingSets.DominatingSets()

希望这有帮助!

答案 2 :(得分:0)

我在这里的accepted answer中学到了很多东西……但是,如果这个目录lib实际上没有包含在PYTHONPATH中,那么在lib / __ init__.py文件中放置内容仍然有问题。

我发现,除了在调用者文件中添加lib的父目录之外,即

sys.path.append( '.../parent_dir_of_lib/lib' )

我要么1)必须在调用者文件中另外执行

import sys
from pathlib import Path
parent_dir_str = str( Path(__file__).resolve().parent )
sys.path.append( parent_dir_str )
 
from analyse_graph import *
from auto_vivification import *
...

或2)必须通过将lib目录放入其__init__.py中来使其“自加载”:

sudo