如何加载 Python 中子目录下的所有模块?
How do I load all modules under a subdirectory in Python?
我将经常使用的模块放在子目录 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
发生这种混淆的部分原因是您的模块名称与您要从中加载的 classes 的名称相同。 (至少,这就是让它变得更加混乱的原因。)您的代码确实正确加载了 classes 所在的模块。但是,它不会从这些模块中加载 classes,并且这就是你真正想做的。
因为你的 class 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
),而不是您想要的 class。
from lib.DominatingSets import DominatingSets
等同于
import lib.DominatingSets
DominatingSets = lib.DominatingSets.DominatingSets
这就是它起作用的原因:这是您要导入到名称 DominatingSets
中的 class。
如果你想让from lib import *
导入子模块中的所有class,你需要将这些class导入到lib
模块中。例如,在 lib/__init__.py
:
from DominatingSets import *
from AnalyzeGraph import *
# ...
在您进行更改时,我建议(像其他人一样)使用正常的 Python 命名约定,并将您的模块名称小写:将 DominatingSets.py
更改为 dominatingsets.py
.那么这段代码就会变成
from dominatingsets import *
from analyzegraph import *
# ...
看你的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
模块,我们试图像模块中的 class 对象一样调用它。让我们现在做:
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
class。
另外,使用 *
from datetime import *
d = datetime(2005, 3, 12)
也可以工作,因为您正在导入 datetime
模块中的所有 classes。
你的代码说:
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()
希望对您有所帮助!
我从这里的 中学到了很多东西...但是如果这个目录 lib 实际上没有包含在 PYTHONPATH 中,我仍然对将什么放入 lib/__init__.py 文件有疑问.
我发现除了在caller文件中添加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 *
...
我将经常使用的模块放在子目录 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
发生这种混淆的部分原因是您的模块名称与您要从中加载的 classes 的名称相同。 (至少,这就是让它变得更加混乱的原因。)您的代码确实正确加载了 classes 所在的模块。但是,它不会从这些模块中加载 classes,并且这就是你真正想做的。
因为你的 class 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
),而不是您想要的 class。
from lib.DominatingSets import DominatingSets
等同于
import lib.DominatingSets
DominatingSets = lib.DominatingSets.DominatingSets
这就是它起作用的原因:这是您要导入到名称 DominatingSets
中的 class。
如果你想让from lib import *
导入子模块中的所有class,你需要将这些class导入到lib
模块中。例如,在 lib/__init__.py
:
from DominatingSets import *
from AnalyzeGraph import *
# ...
在您进行更改时,我建议(像其他人一样)使用正常的 Python 命名约定,并将您的模块名称小写:将 DominatingSets.py
更改为 dominatingsets.py
.那么这段代码就会变成
from dominatingsets import *
from analyzegraph import *
# ...
看你的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
模块,我们试图像模块中的 class 对象一样调用它。让我们现在做:
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
class。
另外,使用 *
from datetime import *
d = datetime(2005, 3, 12)
也可以工作,因为您正在导入 datetime
模块中的所有 classes。
你的代码说:
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()
希望对您有所帮助!
我从这里的
我发现除了在caller文件中添加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 *
...