考虑以下设置:
[~/test]$ tree .
.
├── main.py
└── pkg
├── a.py
├── b.py
├── c.py
└── __init__.py
1 directory, 5 files
[~/test]$ cat main.py
from pkg import a
[~/test]$ cat pkg/a.py
print "Importing b using import statement"
import b
print "\nImporting b dynamically"
import imp
import os
b = imp.load_source('b', os.path.dirname(__file__) + '/b.py')
[~/test]$ cat pkg/b.py
import c
[~/test]$ cat pkg/c.py
print 'Hello from c.py'
我期望的行为是,即使动态导入b.py,b.py中的import c
行也能正常工作,因此此代码将提供以下内容:
[~/test]$ python main.py
Importing b using import statement
Hello from c.py
Importing b dynamically
Hello from c.py
但是我得到以下内容:
[~/test]$ python main.py
Importing b using import statement
Hello from c.py
Importing b dynamically
Traceback (most recent call last):
File "main.py", line 1, in <module>
from pkg import a
File "/home/f.j/test/pkg/a.py", line 8, in <module>
b = imp.load_source('b', os.path.dirname(__file__) + '/b.py')
File "/home/f.j/test/pkg/b.py", line 1, in <module>
import c
ImportError: No module named c
所以问题在这里:
import c
语句也能正常运行?请注意,我可以通过将b.py中的import语句更改为from pkg import c
来实现此功能,但我不想这样做。这里的期望是模块应始终能够直接导入其中包含的其他模块,而无需指定完整的包位置或操纵sys.path
。
我已经在a.py中尝试了以下内容:
# this gives the same behavior as imp.load_source
b = imp.load_module('b', *imp.find_module('b', [os.path.dirname(__file__)]))
# with this I get 'ImportError: No module named b'
b = __import__('b')
答案 0 :(得分:4)
您正在动态导入顶级模块 b
,这是与pkg/b
不同的模块。
由于sys.path
不包含/home/f.j/test/pkg
,因此c
找不到b
,c
正在尝试导入顶级模块pkg.b
那一刻。另一方面,c
模块会尝试首先找到顶级模块pkg.c
,然后找到本地pkg.b
。
而是导入b = imp.load_source('pkg.b', os.path.dirname(__file__) + '/b.py')
:
{{1}}
答案 1 :(得分:1)
我怀疑问题是b.py不理解它是'pkg'的一部分,并且相对路径用于通用导入。
您可以通过将 b.py 修改为:
来导入cfrom pkg import c
更正确的是,您可以通过修改 b.py 来说明 b.py 它是 pkg 的一部分:
__package__ = 'pkg'
import c
我会非常有兴趣了解为什么你需要首先做这件事,因为这看起来很可怕。