Проблема импорта в режиме Python
Я пытаюсь использовать Emacs в качестве редактора python, и он отлично работает, когда я оцениваю (Cc Cc) только отдельные файлы, но когда я оцениваю файл, который импортирует другой файл в том же каталоге, я получаю сообщение об ошибке, файл не может быть импортирован.
Кто-нибудь знает об обходном пути?
Заранее спасибо
edit: Btw, я использую Emacs23 на машине Ubuntu.
Ошибка была,
ImportError: No module named hlutils
Ответы
Ответ 1
Я думаю, что проблема в том, как работает python-режим Emacs Python. Если я наберу M-x run-python
, то я вижу следующее:
>>> import sys
>>> '' in sys.path
False
>>>
тогда как если я запустил интерпретатор python из оболочки, я вижу:
>>> import sys
>>> '' in sys.path
True
>>>
Это похоже на следующий код в run-python
из progmodes/python.el:
(let* ((cmdlist
(append (python-args-to-list cmd)
'("-i" "-c" "import sys; sys.path.remove('')")))
который не имеет комментариев, и следующую полезную запись ChangeLog:
2008-08-24 Romain Francoise <[email protected]>
* progmodes/python.el (run-python): Remove '' from sys.path.
Я бы сказал, что это ошибка в Emacs. Вот обходной путь, который вы можете добавить в файл .emacs:
(defun python-reinstate-current-directory ()
"When running Python, add the current directory ('') to the head of sys.path.
For reasons unexplained, run-python passes arguments to the
interpreter that explicitly remove '' from sys.path. This means
that, for example, using `python-send-buffer' in a buffer
visiting a module code will fail to find other modules in the
same directory.
Adding this function to `inferior-python-mode-hook' reinstates
the current directory in Python search path."
(python-send-string "sys.path[0:0] = ['']"))
(add-hook 'inferior-python-mode-hook 'python-reinstate-current-directory)
Ответ 2
Поскольку ответы, предшествующие этому, были опубликованы, была доступна опция изменения поведения по умолчанию (удаление текущего каталога из пути) для включения cwd в путь.
Итак, простой
(setq python-remove-cwd-from-path nil)
в вашем .emacs должен исправить это.
Ответ 3
Я импортирую локальные модули из одного и того же каталога, просто отлично, используя py-execute-buffer
.
Ваша проблема может быть связана с тем, как py-execute-buffer
идет о своей работе: он сохраняет буфер в tmp файле (в каталоге py-temp-directory
), а затем передает этот файл на Python. В вашем случае на систему может повлиять каталог файла temp.
Другой аспект: py-execute-buffer
выполняет разные действия с файлом tmp в зависимости от наличия или отсутствия буфера интерпретатора Python. Попробуйте свой случай с работающим интерпретатором и без него (просто запустите буфер интерпретатора).
Ответ 4
У меня такая же проблема, если вы не хотите редактировать файл .emacs, вы можете поместить это в начало своего script:
import sys
import os
sys.path.append(os.getcwd())
Он временно добавляет текущую рабочую директорию к вашему sys.path,
Ответ 5
Откройте терминал и введите emacs -q
. Это запускает emacs без загрузки файла init (.emacs
). Происходит ли такое же поведение? Если нет, значит это проблема в вашем файле .emacs.
Edit:
Когда вы запускаете script с помощью C-c C-c из режима Python Emacs, каталог, содержащий script, не добавляется в начало sys.path
. Я нашел это, поставив
import sys
print sys.path
в верхней части теста script. Вот почему Python не находит другие модули, которые находятся в одном каталоге.
Когда вы запускаете script из командной строки, Python добавляет каталог, содержащий script в sys.path
. Вот почему тот же script работает из командной строки.
Вы можете исправить это, отредактировав файл ~/.bashrc и добавив
export PYTHONPATH=/path/to/Python/scripts
После сохранения ~/.bashrc закройте emacs и запустите его снова, чтобы убедиться, что изменение на .bashrc становится эффективным.
Ответ 6
Я действительно плохо разбираюсь с emacs lisp, и я никогда не использовал Ubuntu, поэтому следующее может потребовать некоторой настройки, но если код отлично работает с оболочкой, почему бы просто не установить emacs для запуска команды оболочки? Просто поставьте:
(defun shell-compile ()
(interactive)
(shell-command (concat "python " (buffer-file-name))))
(add-hook 'python-mode-hook
(lambda () (local-set-key (kbd "\C-c\C-c") 'shell-compile)))
в файл .emacs. Должно быть гораздо более чистые способы сделать это, но это, по крайней мере, поможет вам работать.
Ответ 7
улучшение существующего ответа выше: eval this в вашем буфере с нуля, чтобы добавить cwd обратно в pythonpath
(defun python-reinstate-current-directory ()
(python-send-string "sys.path[0:0] = ['']"))
(add-hook 'inferior-python-mode-hook 'python-reinstate-current-directory)
Ответ 8
Я придумал очень простое решение.
Просто добавьте к .emacs
следующую строку:
(setenv "PYTHONPATH" "/path/to/where/modules/are")
Он установит значение переменной среды с именем variable в значение.
Теперь, набрав интерпретатор emacs python...
>>> import sys
>>> sys.path
>>> ['/path/to/where/modules/are', '/usr/share/emacs/23.1/etc' ... ]
... и пользовательская работа import
.