3

私はvirtualenvで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で実行するとロードする原因は何でしょうか?

4

2 に答える 2

7

誤った機能に出くわしました:相対インポート. と言うとfrom couchdb.client...、Python は最初にoffers.という名前のモジュールを探しますcouchdb。作業中のファイルoffers/couchdb.py!

通常の修正は、この動作を無効にすることですが、とにかく Python 3 では廃止されています。これをファイルの Python コードの最初の行として追加します。

from __future__ import absolute_import

couchdb次に、Pythonは、現在のモジュールの兄弟ではなく、名前が付けられたトップレベルモジュールからインポートしたいと想定します(そうします)。

残念ながら、この場合、ファイルを直接実行しているため、Python は引き続きoffers/その検索パスに追加します。モジュールを意図したファイルを実行する場合、次のように実行できます-m

python -m offers.couchdb

これで動作するはずです。

(もちろん、 file という名前を付けないこともできますcouchdb.py。しかし、相互作用またはラップするものにちなんでモジュールの名前を付けることは非常に便利です。)

于 2013-01-16T20:19:31.090 に答える
0

編集: 上記の Eevee の回答を参照してください。それでも、これは他の人に役立つかもしれません(?):

おそらく、virtualenvにcouchdbをインストールしていませんか? それがインタープリターで機能する理由を説明できます(インタープリターがvirtualenvから起動されていない場合)。

そこにインストールするか、--site-packages で virutalenv を作成してください。

于 2013-01-16T20:20:19.030 に答える