2

mine.py が moduleA と moduleB をインポートしたいが、moduleA と moduleB がそれぞれ「moduleC」というモジュールをインポートしようとしているとします。これらは 2 つの異なるモジュールで、どちらも「moduleC」という名前になっています。mine.py が実行されると、sys.path に応じて、moduleA または moduleB のいずれかが正しい「moduleC」を取得し、もう一方は驚き、混乱が生じます。

moduleA と moduleB が別の作成者によって作成され、どちらも私たちではない場合、それらのモジュールを変更しないことをお勧めします。moduleA または moduleB を変更しない mine.py の作成者が利用できる解決策はありますか?

次の質問は、あなたが moduleA または moduleB の作成者である場合に、この問題を解決する方法を尋ねます。

同名のモジュールが存在する場合の組み込みライブラリからのインポート

同じ名前のローカルモジュールがある場合、Python で標準ライブラリモジュールにアクセスする方法は?

私の特定のケース

Python デバッガー pdb で PyMOL というプログラムを実行したいと考えています。残念ながら、PyMOL にはインポートする「cmd.py」があり、pdb がインポートする通常の cmd と競合します。

PyMOL インストールの関連部分は次のようになります。

pymol/
    __init__.py
    cmd.py

PyMOL は を実行することで実行され__init__.pyます。このファイルはcmdfrom pymol import cmd.

BrenBarnが指摘したことから作業すると、これまでpdbのところ、ディレクトリをcmd一時的に削除することで、 . その後、PyMOL がそのインポートを試みるとクラッシュします。どういうわけか、インポートの前に、インポートの後に、インポート モジュールの検索からPython を削除する必要があります。pymolsys.pathcmdcmdPyMOLpdb

最小限の例

$ ls
pymol/
$ ls pymol/
__init__.py  cmd.py

初期化.py

# insert some code into __init__.py directly

import sys
pymol_path = sys.path[0]
sys.path[0] = ""
import pdb
sys.path[0] = pymol_path

from pymol import cmd

# test a sandwich of calls that require each "cmd" modules
pdb.set_trace()    
cmd.foo()    
pdb.set_trace()
cmd.foo()

print "done!"

# original PyMOL __init__.py code would follow

cmd.py

def foo():
    print("cmd.foo()")

それを試してみてください

$ PYTHONPATH= python ./pymol/__init__.py
> /Users/khouli/scr/pymol_scr/pymol/__init__.py(11)<module>()
-> cmd.foo()
(Pdb) continue
cmd.foo()
> /Users/khouli/scr/pymol_scr/pymol/__init__.py(13)<module>()
-> cmd.foo()
(Pdb) continue
cmd.foo()
done!

編集:上記の方法は機能しているように見えますが、BrenBarnの回答が述べているように、質問が最初に求めたように、すべてのサードパーティコードを変更しないままにする解決策はおそらくありません. これは、PyMOL の癖によるものです。

4

1 に答える 1

2

問題はインポートだけではなく、スクリプトとして実行しているという事実にあります。 __init__.pyスクリプトを実行すると、Python はスクリプトを含むディレクトリを の先頭に追加しますsys.path。これは、後続のすべてのインポートにグローバルに影響します。

変更したくないファイルを直接実行している場合、何もカスタマイズする方法はありません。sys.path最初に独自のコードを実行して、必要な方法でパスを設定しない限り、卑劣な操作を行うことはできません。ファイルを実行する代わりにインポートすると、独自のコードを使用してパスを微調整できます。

この問題はある程度 PyMOL に固有のものであると思われますが、残念ながら、この点に関してうまく設計されていないようです。ここのソース コードを見ると、PyMOL には、実行中のバージョン自体にさまざまな属性があるかどうかを確認する__init__.pyなど、奇妙なことを行う多くのカスタム コードが含まれていることがわかります。import __main__そのファイルのコメントに記載されている「サポートされていない/実験的な」方法を試すことができます。これには、PyMOL を実行する代わりにインポートすることが含まれます。私は PyMOL について何も知らないので、それがどのように機能するかわかりません。

PyMOL の作成者に連絡して、これを修正するよう提案する価値があるかもしれません。

于 2014-11-20T04:47:45.000 に答える