Проблема с импортом в режиме Python

Я пытаюсь использовать Emacs в качестве редактора Python, и он отлично работает, когда я оцениваю (C-c C-c) только отдельные файлы, но когда я оцениваю файл, который импортирует другой файл в тот же каталог, я получаю сообщение об ошибке, говорящее, что файл не может быть импортированы.

Кто-нибудь знает обходной путь?

заранее спасибо

edit: Кстати, я использую Emacs23 на машине с Ubuntu.

Ошибка была,

  ImportError: No module named hlutils 

person smith    schedule 17.04.2010    source источник
comment
Я не пытаюсь проявить к вам неуважение, я говорю это только потому, что у меня никогда не было таких проблем, и я просто хочу убедиться в ваших, но когда вы пытаетесь нормально запустить файл с помощью python, вне emacs, он действительно запускается правильно, да?   -  person Nikwin    schedule 17.04.2010
comment
Кроме того, попробуйте запустить следующий код Python: import os print os.listdir('.') и посмотрите, какую папку он выводит.   -  person Nikwin    schedule 17.04.2010
comment
Да, я написал это в Scite, и это сработало. Я переключаюсь на emacs, потому что он немного более динамичный (у него есть реплика для быстрого тестирования кода, тогда как scite просто запускает команду python и показывает вывод). Без обид конечно :)   -  person smith    schedule 17.04.2010
comment
Я предполагаю, что он установил текущий рабочий каталог на что-то другое, чем то, что вы ожидаете. Используйте os.getcwd(), чтобы выяснить, где вас на самом деле бросили...   -  person Donal Fellows    schedule 17.04.2010
comment
привет, я попробовал эту команду, но кажется, что текущий каталог правильный.   -  person smith    schedule 17.04.2010
comment
Что происходит, когда вы print sys.path? Каталог, содержащий hlutils в sys.path?   -  person unutbu    schedule 17.04.2010
comment
нет, его нет в sys.path, но это всего лишь небольшое приложение, нужно ли мне каждый раз добавлять свою папку в переменную sys.path, чтобы сделать ее узнаваемой?   -  person smith    schedule 17.04.2010
comment
У меня есть идея, как решить проблему. Смотрите мое редактирование ниже.   -  person unutbu    schedule 17.04.2010
comment
Ваш REPL запускается в контексте файла, из которого вы запускаете REPL. Подумайте о структуре вашего процесса разработки. Если вы добавите в свой REPL кучу разных контекстов, то, что вы в нем напишете, может сбивать с толку.   -  person Teodor    schedule 20.07.2018


Ответы (9)


Я думаю, что проблема в том, как 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('')")))

который не имеет комментариев, и следующую полезную запись в журнале изменений:

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's 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's search path."
  (python-send-string "sys.path[0:0] = ['']"))

(add-hook 'inferior-python-mode-hook 'python-reinstate-current-directory)
person Jim Blandy    schedule 02.08.2010
comment
Согласно twistedmatrix.com/pipermail/cvstoys-list/2003q3/000114.html - это было исправление безопасности, другая информация здесь: old.nabble.com/ - person Danny Staple; 23.05.2011

Поскольку ответы, предшествующие этому, были опубликованы, появилась возможность изменить поведение по умолчанию (удаление текущего каталога из пути), чтобы включить cwd в путь.

Так просто

(setq python-remove-cwd-from-path nil)

в вашем .emacs это должно быть исправлено.

person user1244215    schedule 05.03.2012
comment
Вы также можете установить эту переменную в файле .emacs через M-x customize-variable [RET] python-remove-cwd-from-path [RET]. - person DavidRR; 14.01.2015

У меня та же проблема, если вы не хотите редактировать свой файл .emacs, вы можете поместить это в начало вашего скрипта:

import sys
import os
sys.path.append(os.getcwd())

Он временно добавляет текущий рабочий каталог в ваш sys.path,

person tjb    schedule 09.12.2010
comment
Примечание. Вы можете добавить текущий рабочий каталог в начало пути с помощью sys.path.insert(0, os.getcwd()) - person kkurian; 14.10.2012

Я отлично импортирую локальные модули из того же каталога при использовании py-execute-buffer.

Ваша проблема может быть связана с тем, как py-execute-buffer выполняет свою работу: он сохраняет буфер в файл tmp (в каталоге py-temp-directory), а затем передает этот файл в Python. В вашем случае на систему может повлиять каталог временных файлов.

Другой аспект: py-execute-buffer делает разные вещи с файлом tmp в зависимости от того, существует буфер интерпретатора Python или нет. Попробуйте свой случай с работающим интерпретатором и без (просто убей буфер интерпретатора).

person halloleo    schedule 30.07.2010

Я действительно очень плохо разбираюсь в 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. Должны быть гораздо более чистые способы сделать это, но это, по крайней мере, заставит вас работать.

person Nikwin    schedule 17.04.2010
comment
Спасибо, это работает хорошо. Но вместо выполнения команды оболочки, если она запускает интерпретатор Python и отправляет содержимое буфера интерпретатору Python, это было бы здорово, это единственная функция, которую предлагает режим Python, которую я действительно хочу, просто не могу заставить ее работать; ) - person smith; 17.04.2010

Откройте терминал и введите emacs -q. Это запускает emacs без загрузки файла инициализации (.emacs). Происходит ли такое же поведение? Если нет, значит проблема в вашем файле .emacs.

Изменить:

Когда вы запускаете скрипт с помощью C-c C-c в режиме Python Emacs, каталог, содержащий скрипт, не добавляется в начало sys.path. Я узнал это, поставив

import sys
print sys.path

в верхней части тестового сценария. Вот почему Python не находит другие модули, находящиеся в том же каталоге.

Когда вы запускаете сценарий из командной строки, Python добавляет каталог, содержащий сценарий, в sys.path. Вот почему тот же скрипт работает из командной строки.

Вы можете исправить это, отредактировав файл ~/.bashrc и добавив

export PYTHONPATH=/path/to/Python/scripts

После сохранения ~/.bashrc закройте emacs и запустите его снова, чтобы убедиться, что изменение в .bashrc вступило в силу.

person unutbu    schedule 17.04.2010
comment
Является ли каталог сценариев каталогом моего файла или это специальная папка в python? я попробовал путь/к/python как /usr/share/python, но это не сработало. извините, я новичок в Linux, в Windows я знаю, что моя папка python находится в c:/python25, но в Linux есть много папок с именем python, поэтому я не могу выбрать правильную. - person smith; 17.04.2010
comment
@smith, извините, я должен был быть более ясным. Измените /path/to/Python/scripts на каталог, содержащий hlutils.py. - person unutbu; 17.04.2010
comment
Привет, я отредактировал файл .bashrc, но он все равно не работал, даже после того, как я попробовал некоторые альтернативы, такие как PYTHONPATH=$PYTHONPATH:/home/desktop/project export PYTHONPATH . Думаю, моя судьба :( Большое спасибо за ваши предложения и терпение, с другой стороны, я узнал кое-что о своей структуре папок :) - person smith; 17.04.2010
comment
Хм, извините тогда. Я думал, что у меня это получилось... :-/ - person unutbu; 17.04.2010

улучшение существующего ответа выше: оцените это в своем рабочем буфере, чтобы добавить cwd обратно в pythonpath

(defun python-reinstate-current-directory ()
  (python-send-string "sys.path[0:0] = ['']"))
(add-hook 'inferior-python-mode-hook 'python-reinstate-current-directory)
person Dustin Getz    schedule 25.08.2012

Я придумал очень простое решение. Просто добавьте в свой .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 работают.

person peixe    schedule 30.08.2012

У меня такая же проблема. Я заметил, что когда я использую команду run-python в Emacs, она запускает версию Python по умолчанию (2.7) в моей сборке Ubuntu. Это не правильно. Установил Анаконду. Когда я запускаю Python из командной строки, запускается моя установка Anaconda (3.7).

Посмотрите ответ Джеймса Андерсона на этот пост:

Emacs и обходной путь

Он прав в моем случае. Если я запускаю Emacs из командной строки, Emacs знает о захваченном пути, добавленном Анакондой. Я уверен, что мог бы каким-то образом включить это в свою инициализацию Emacs, если бы мне было небезразлично.

person Jai Jeffryes    schedule 27.09.2020