【发布时间】:2020-02-23 20:18:21
【问题描述】:
这个问题与Can't import module with importlib.import_module有关,我认为这根本不是问题的根源。
我试图了解交互式解释器与非交互式脚本中使用的importlib 存在差异的原因,因为我得到的结果不同。
我有一个包含myscript.py 的文件夹,我希望它从初始工作目录的子文件夹my_subdir 中导入一个名为module 的模块。我想通过进入该目录并在那里工作来做到这一点。我知道访问子目录中的模块还有其他解决方案,但这是我想谈谈的用例。
以下是myscript.py的内容,它只是移动到子目录并尝试从那里导入模块,然后从模块中调用一些hello-world函数:
#!/home/chris/anaconda2/bin/python
import sys
import platform
import os
import importlib
print("Python version "+ platform.python_version())
print(sys.path)
os.chdir('my_subdir')
my_module = importlib.import_module('module')
my_module.my_function()
当我从命令行运行它时,Python 找不到该模块。好像导入系统不知道os.chdir()的目录变化:
(base) chris@linux-om3m:~/workspace> python myscript.py
Python version 2.7.15
['/home/chris/workspace', '/home/chris/anaconda2/lib/python27.zip', '/home/chris/anaconda2/lib/python2.7', '/home/chris/anaconda2/lib/python2.7/plat-linux2', '/home/chris/anaconda2/lib/python2.7/lib-tk', '/home/chris/anaconda2/lib/python2.7/lib-old', '/home/chris/anaconda2/lib/python2.7/lib-dynload', '/home/chris/anaconda2/lib/python2.7/site-packages', '/home/chris/anaconda2/lib/python2.7/site-packages']
Traceback (most recent call last):
File "myscript.py", line 11, in <module>
my_module = importlib.import_module('module')
File "/home/chris/anaconda2/lib/python2.7/importlib/__init__.py", line 37, in import_module
__import__(name)
ImportError: No module named module
但是,当我在交互式解释器中键入相同的脚本时,它可以正常工作:
(base) chris@linux-om3m:~/workspace> python
Python 2.7.15 | packaged by conda-forge | (default, Jul 2 2019, 00:39:44)
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> import platform
>>> import os
>>> import importlib
>>> print("Python version "+ platform.python_version())
Python version 2.7.15
>>> print(sys.path)
['', '/home/chris/anaconda2/lib/python27.zip', '/home/chris/anaconda2/lib/python2.7', '/home/chris/anaconda2/lib/python2.7/plat-linux2', '/home/chris/anaconda2/lib/python2.7/lib-tk', '/home/chris/anaconda2/lib/python2.7/lib-old', '/home/chris/anaconda2/lib/python2.7/lib-dynload', '/home/chris/anaconda2/lib/python2.7/site-packages', '/home/chris/anaconda2/lib/python2.7/site-packages']
>>> os.chdir('my_subdir')
>>> my_module = importlib.import_module('module')
>>> my_module.my_function()
Here I am!
>>>
我可以通过在执行os.chdir 后手动更新sys.path 和sys.path.append(os.getcwd()) 来解决此问题 - 但我不明白为什么这仅在非交互模式下才有必要。
我唯一注意到(并在此处粘贴的输出中打印)是在交互式解释器下,sys.path 有一个空字符串条目,而在非交互模式下,它包含我调用的工作目录蟒蛇。
我知道我可以使用相对导入来解决这个问题,现在我正在使用sys.path.append(os.getcwd()) 来解决这个问题,但我想了解为什么交互式运行与非交互式运行之间存在差异。
我在 Python 2.7 和 Python 3.6 中得到了相同的结果。
【问题讨论】:
-
其实我也可以在非交互模式下通过
sys.path.append('')修复它,所以我猜''有特殊含义。但问题仍然是为什么交互式解释器在sys.path上有空字符串,而非交互式解释器没有(因此我们在两者之间有完全不同的行为!)。
标签: python python-3.x linux python-2.7