【问题标题】:Python-mode import problemPython模式导入问题
【发布时间】:2011-02-09 03:37:10
【问题描述】:

我正在尝试将 Emacs 用作 python 编辑器,当我只评估(Cc Cc)单个文件时它可以正常工作,但是当我评估在同一目录中导入另一个文件的文件时,我收到一条错误消息,提示文件无法导入。

有人知道解决方法吗?

提前致谢

编辑:顺便说一句,我在 Ubuntu 机器上使用 Emacs23。

错误是,

  ImportError: No module named hlutils 

【问题讨论】:

  • 我不是要不尊重你,我只是这样说,因为我从来没有遇到过这样的问题,我只是想确定你的问题,但是当你尝试用 python 正常运行文件时,在 emacs 之外,它确实可以正常运行,对吧?
  • 另外,尝试运行以下 python 代码: import os print os.listdir('.') 并查看它打印出的文件夹。
  • 是的,我在 Scite 中编写了它并且它有效。我正在切换到 emacs,因为它更具动态性(它有一个 repl 可以快速测试代码,而 scite 只是运行一个 python 命令并显示输出)。当然没有冒犯:)
  • 我猜它设置的当前工作目录不是你所期望的。使用os.getcwd() 找出你真正被抛弃的地方......
  • 嗨,我试过那个命令,但当前目录似乎是正确的。

标签: python emacs


【解决方案1】:

我认为问题在于 Emacs 的 python 模式运行 Python 的方式。如果我输入M-x run-python,那么我会看到:

>>> import sys
>>> '' in sys.path
False
>>> 

而如果我从 shell 运行 python 解释器,我会看到:

>>> import sys
>>> '' in sys.path
True
>>> 

这似乎是由于 progmodes/python.el 中 run-python 中的以下代码:

(let* ((cmdlist
    (append (python-args-to-list cmd)
        '("-i" "-c" "import sys; sys.path.remove('')")))

没有评论,以及以下有用的变更日志条目:

2008-08-24  Romain Francoise  <romain@orebokech.com>

        * 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)

【讨论】:

【解决方案2】:

由于发布了此答案之前的答案,因此提供了一个选项来更改默认行为(从路径中删除当前目录)以将 cwd 包含在路径中。

这么简单

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

在你的 .emacs 中应该可以解决这个问题。

【讨论】:

  • 你也可以通过M-x customize-variable [RET] python-remove-cwd-from-path [RET]在你的.emacs文件中设置这个变量。
【解决方案3】:

我也有同样的问题,如果您不想编辑 .emacs 文件,可以将其放在脚本的开头:

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

它将当前工作目录临时添加到您的 sys.path,

【讨论】:

  • 注意:您可能希望使用 sys.path.insert(0, os.getcwd()) 将当前工作目录添加到路径的开头
【解决方案4】:

当使用py-execute-buffer 时,我可以从同一目录导入本地模块。

您的问题可能与 py-execute-buffer 的工作方式有关:它将缓冲区保存到一个 tmp 文件(在目录 py-temp-directory 中),然后将此文件传递给 Python。在您的情况下,系统可能会受到临时文件目录的影响。

另一方面:py-execute-buffer 对 tmp 文件执行不同的操作,具体取决于 Python 解释器缓冲区是否存在。尝试使用正在运行的解释器而不是(只需终止解释器缓冲区)。

【讨论】:

    【解决方案5】:

    我对 emacs lisp 真的很不好,而且我从来没有使用过 Ubuntu,所以下面可能需要一些调整,但是如果代码在 shell 中运行良好,为什么不设置 emacs 来运行 shell 命令呢?简单地说:

    (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 文件中。必须有更清洁的方法来做到这一点,但这至少会让你工作。

    【讨论】:

    • 谢谢,这很好用。但是,如果它启动一个 python 解释器并将缓冲区内容发送到 python 解释器,而不是执行一个 shell 命令,那就太好了,这就是我真正想要的 python-mode 提供的一个功能,只是无法让它工作; )
    【解决方案6】:

    打开终端并输入emacs -q。这将启动 emacs 而不加载 init 文件 (.emacs)。是否会发生相同的行为?如果不是,则表示您的 .emacs 文件有问题。

    编辑:

    当您在 Emacs 的 Python 模式下使用 C-c C-c 运行脚本时,包含该脚本的目录不会添加到 sys.path 的开头。我发现了这一点

    import sys
    print sys.path
    

    在测试脚本的顶部。这就是 Python 没有找到位于同一目录中的其他模块的原因。

    当您从命令行运行脚本时,Python 会将包含该脚本的目录添加到 sys.path。这就是为什么相同的脚本可以在命令行中工作的原因。

    您可以通过编辑 ~/.bashrc 文件并添加来解决此问题

    export PYTHONPATH=/path/to/Python/scripts
    

    保存~/.bashrc后,关闭emacs并重新启动,确保对.bashrc的修改生效。

    【讨论】:

    • 脚本目录是我的文件目录还是python中的特殊文件夹?我尝试将 path/to/python 作为 /usr/share/python 但它没有用。抱歉,我是 linux 新手,在 windows 中我知道我的 python 文件夹在 c:/python25 中,但是 linux 有很多名为 python 的文件夹,因此我无法找出正确的文件夹
    • @smith,对不起,我应该更清楚。将/path/to/Python/scripts 更改为包含hlutils.py 的目录。
    • 嗨,我编辑了 .bashrc 文件,但即使尝试了 PYTHONPATH=$PYTHONPATH:/home/desktop/project export PYTHONPATH 之类的替代方法,它仍然无法工作。我猜我的命运:(。非常感谢你的建议和耐心,从好的方面来说,我学到了一些关于我的文件夹结构的东西:)
    • 嗯,对不起。我以为我把这个钉牢了……:-/
    【解决方案7】:

    改进上面的现有答案:在您的暂存缓冲区中对此进行评估,以将 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 的环境变量的值设置为 value。

      现在,输入 emacs python 解释器...

      >>> import sys
      >>> sys.path
      >>> ['/path/to/where/modules/are', '/usr/share/emacs/23.1/etc' ... ]
      

      ...自定义imports 工作。

      【讨论】:

        【解决方案9】:

        我也有同样的问题。我注意到当我在 Emacs 中使用 run-python 命令时,它会在我的 Ubuntu 版本上运行默认的 Python 版本(2.7)。那是不对的。我安装了蟒蛇。当我从命令行启动 Python 时,它会启动我的 Anaconda 安装 (3.7)。

        查看 James Anderson 在这篇文章中的回答:

        Emacs and condo workaround

        在我的情况下他是对的。如果我从命令行启动 Emacs,Emacs 就会知道 Anaconda 添加的劫持路径。我敢肯定,如果我愿意的话,我可以以某种方式将它加入到我的 Emacs 初始化中。

        【讨论】:

          猜你喜欢
          • 2011-05-31
          • 1970-01-01
          • 1970-01-01
          • 2015-09-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-07-25
          相关资源
          最近更新 更多