【问题标题】:How do I load all modules under a subdirectory in Python?如何在 Python 的子目录下加载所有模块?
【发布时间】:2016-06-29 18:24:59
【问题描述】:

我将常用模块放在子目录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

【问题讨论】:

  • 我在您发布的代码中看不到任何错误。但是,由于from lib import * 运行lib 文件夹中所有文件的代码,错误可能来自您未在此处发布的一段代码。检查引发的错误给出的行号。
  • @loutre 谢谢。我更新了问题,请检查。
  • 我的意思是错误可能来自 /lib/*.py 文件之一中的一段代码。你说from lib.DominatingSets import * 有效,但其他人呢? (AnalyzeGraphAutoVivification 等等……)
  • 不是单独的 .. 如果您在 linux 上,每个模块名称的顶部目录中的 grep -r "modulename(" . ?查看您是否有名称冲突的方法。如果你去某个地方 blah = AnalyzeGraph(stuff) 它将命中模块名称,而不是类。嗯,可能需要测试 AnalyzeGraph.xxx to0。
  • 你试过 lib/dominationsets.py 吗?

标签: python package python-import python-module


【解决方案1】:

发生这种混淆的部分原因是您的模块名称与您要从中加载的类的名称相同。 (至少,这使它更令人困惑。)您的代码确实正确加载了您的类所在的模块。但是,它不会从这些模块中加载类,而这正是您真正想要做的。

因为您的课程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 *
# ...

【讨论】:

【解决方案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()

希望这会有所帮助!

【讨论】:

    【解决方案3】:

    我从这里的accepted answer 学到了很多东西......但是如果这个目录 lib 没有真正包含在 PYTHONPATH 中,我仍然无法在 lib/__init__.py 文件中放入什么。

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

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

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

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

    或者 2) 必须使 lib 目录“自动加载”,方法是将其放在其 __init__.py 中:

    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 *
    ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-22
      • 2020-02-23
      • 2013-05-27
      • 2017-01-02
      • 2012-02-15
      • 1970-01-01
      • 2012-03-27
      • 1970-01-01
      相关资源
      最近更新 更多