虚拟环境中的Python模块

3

我在虚拟环境中使用Python。我有以下模块:

offers/couchdb.py:

from couchdb.client import Server

def get_attributes():
    return [i for i in Server()['offers']]

if __name__ == "__main__":
    print get_attributes()

当我从文件中运行它时,会得到以下结果:
$ python offers/couchdb.py
Traceback (most recent call last):
  File "offers/couchdb.py", line 1, in <module>
    from couchdb.client import Server
  File "/Users/bartekkrupa/D/projects/commercial/echatka/backend/echatka/offers/couchdb.py", line 1,     in <module>
    from couchdb.client import Server
ImportError: No module named client

但是当我将它粘贴到解释器中时,它就能够工作:
$ python
Python 2.7.2 (default, Jun 20 2012, 16:23:33) 
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from couchdb.client import Server
>>> 
>>> def get_attributes():
...     return [i for i in Server()['offers']]
... 
>>> if __name__ == "__main__":
...     print get_attributes()
... 

Python从文件运行模块时为什么不能加载couchdb模块,但在REPL中运行时可以?
2个回答

7
您遇到了一个不良功能:相对导入。当您输入from couchdb.client...时,Python首先会查找一个名为couchdb的模块在offers.下,它也找到了一个:您正在使用的文件offers/couchdb.py
通常的解决方法是禁用这个行为,这在Python 3中已经不存在了。将以下代码作为文件中的第一行即可:
from __future__ import absolute_import

那么 Python 将会认为你想要从一个名为 couchdb 的顶级模块导入(你确实想要这样做),而不是当前模块的同级模块。

不幸的是,在这种情况下,你正在直接运行该文件,Python 仍然会将 offers/ 添加到其搜索路径中。当运行一个旨在作为模块的文件时,你可以使用 -m 来运行它:

python -m offers.couchdb

现在应该可以工作了。

(当然,你也可以不把文件命名为couchdb.py。但我发现给模块命名与其交互或包装的东西非常有用。)


0

编辑: 请参考上面Eevee的答案 - 我认为那更合适。 不过,这可能对其他人有帮助(?):

也许您没有在虚拟环境中安装couchdb? 如果解释器不是从虚拟环境启动,那可能就可以解释为什么它在解释器中运行。

要么在其中安装它,要么使用--site-packages创建virutalenv。


解释器肯定是从虚拟环境中启动的 :) - bartek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接