Этот вопрос относится к Невозможно импортировать модуль с importlib.import_module , который, я не думаю, вообще дошел до корня проблемы.
Я пытаюсьчтобы понять причину различий с importlib
, используемым в интерактивном интерпретаторе, и неинтерактивным сценарием, потому что с каждым я получаю разные результаты.
У меня есть папка, содержащая myscript.py
, и яхотите импортировать модуль с именем module
из подпапки, my_subdir
исходного рабочего каталога. Я хочу сделать это, перейдя в этот каталог и работая там. Я знаю, что есть другие решения для доступа к модулю в подкаталоге, но об этом я бы хотел поговорить.
Ниже приведено содержимое 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!
>>>
Я могу исправить эту проблему, вручную обновив sys.path
на sys.path.append(os.getcwd())
после выполнения os.chdir
- но я не понимаю, почему это необходимо только в неинтерактивном режиме.
Единственное, что я замечаю (и напечатано здесь в вставленном выводе), это то, что в интерактивном интерпретаторе sys.path
имеет запись с пустой строкой, тогда как в неинтерактивном режиме он содержит рабочий каталог, в котором я вызывал python.
Я знаю, что могу решить эту проблему, используя относительный импорт, и сейчас я решаю проблему, используя sys.path.append(os.getcwd())
, но я хотел бы понять, почему существует разница между интерактивным и не-интерактивно.
Я получаю одинаковые результаты с Python 2.7 и Python 3.6.