2

という名前のローカル モジュールtokenize.pyがあり、同じ名前の標準ライブラリ モジュールをマスクします。これは、外部モジュール (sklearn.linear_model) をインポートしようとしたときにのみ発見されました。これはimport tokenize、標準ライブラリ モジュールを取得し、取得することを期待していますが、代わりにローカル モジュールを取得します。

これは、同じ名前のローカル モジュールがある場合、Python で標準ライブラリ モジュールにアクセスする方法に関連していますか? 、ただし、上記のソリューションを適用するには外部モジュールを変更する必要があるため、設定は異なります。

オプションは local の名前を変更することtokenize.pyですが、「トークン化」がモジュールの役割を最もよく表しているため、そうしないことをお勧めします。

問題を説明するために、モジュール構造のスケッチを次に示します。

   \my_module
      \__init__.py
      \tokenize.py
      \use_tokenize.py

use_tokenize.py には、次のインポートがあります。

import sklearn.linear_model

を呼び出すと、次のエラーが発生しますpython my_module/use_tokenize.py

Traceback (most recent call last):
  File "use_tokenize.py", line 1, in <module>
    import sklearn.linear_model
  <...>
  File "<EDITED>/lib/python2.7/site-packages/sklearn/externals/joblib/format_stack.py", line 35, in <module>
    generate_tokens = tokenize.tokenize
AttributeError: 'module' object has no attribute 'tokenize'

外部モジュールをインポートするときにローカル モジュールを抑制する方法はありますか?

編集: Python のバージョンによって解決策が異なるというコメントがあったため、タグとして python2.7 を追加しました

4

2 に答える 2

4

問題はモジュール名ではなく、スクリプトのようにモジュールを実行していることです。Python がスクリプトを実行すると、スクリプトを含むディレクトリが の最初の要素として追加されるため、どこからでもすべてのモジュール ルックアップで最初にそのディレクトリが検索されます。sys.path

これを回避するには、代わりにモジュールとして実行するように Python に依頼します。

python -m my_module.use_tokenize

または、もちろん、実行可能なスクリプトをモジュール階層から除外することもできます。

于 2013-03-01T06:03:53.003 に答える
0

The paths that the interpreter searches for modules in are listed in sys.path. To prevent the third-party module from seeing the local module at import, we remove . from the path. This can be achieved by:

import sys
sys.path = sys.path[1:]
import sklearn.linear_model #using the original example.

However, this will not work if the local tokenize has already been imported, and it will also prevent the local tokenize from being imported, even if we restore the old sys.path as follows:

import sys
old_path = sys.path
sys.path = sys.path[1:]
import sklearn.linear_model #using the original example.
sys.path = old_path

This is because the Python interpreter maintains an internal mapping of imported modules, so that later requests for the same module are fulfilled from this mapping. This mapping is global to the interpreter, so import tokenize returns the same module from any code that runs it - which is exactly the behavior we are trying to alter. To achieve this, we have to alter this mapping. The easiest way to do this is to simply delete the relevant entry from sys.modules.

import sys
old_path = sys.path
sys.path = sys.path[1:]
import sklearn.linear_model #using the original example.
sys.path = old_path
del sys.modules['tokenize'] #get of the mapping to the standard library tokenize
import tokenize #cause our local tokenize to be imported    
于 2013-03-04T00:06:22.770 に答える