virtualenv中的python模块

virtualenv中的python模块,python,virtualenv,Python,Virtualenv,我在virtualenv中使用python。我有以下模块: 提供/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

我在virtualenv中使用python。我有以下模块:

提供/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不会加载couchdb模块,但在REPL中运行会加载couchdb模块,这可能是什么原因呢?

您偶然发现了一个错误特性:相对导入。当您从couchdb.client…中说
时,Python首先会在
提供项下查找名为
couchdb
的模块。它会找到一个:您正在处理的文件,
提供了/couchdb.py

通常的修复方法是禁用此行为,这在Python3中已经没有了。将其作为文件中Python代码的第一行:

from __future__ import absolute_import
然后,Python将假定您希望从名为
couchdb
(您确实需要)的顶级模块导入,而不是从当前模块的同级模块导入

不幸的是,在本例中,您直接运行该文件,Python仍然会向其搜索路径添加
offers/
。当运行打算作为模块的文件时,您可以使用
-m

python -m offers.couchdb
现在应该可以了

(当然,您可以不命名您的文件
couchdb.py
。但我发现以模块与之交互或包装的对象命名非常有用。)

编辑: 见上文Eevee的答案——我认为它更适合。 不过,这可能对其他人有所帮助(?):

也许您没有在virtualenv中安装couchdb? 这可以解释为什么它在解释器中工作(如果解释器不是从virtualenv启动的)


可以在那里安装它,也可以使用--site包创建virtualenv。

解释器肯定是从virtualenv启动的:)
python -m offers.couchdb