2009-08-27 8 views
1

申し訳ありませんが、私は私の問題の原因を理解すれば、それを変更します 私は以下の構造を有する:のpythonを通報しますと、一般的なタイトルの__import__

foo/ 
foo/__init__.py 
foo/bar/ 
foo/bar/__init__.py 
foo/bar/some_module.py 

私はそうすることによってsome_moduleをインポートしようとすると:

from foo.bar import some_module 

チャームのように機能します。 しかし、実行時にインポートするモジュールの名前しか知っていないので、これは私には良いことではありません。私が試してみると:

from foo.bar import * 
mod=__import__('some_module') 

私はエラーが発生します。私は何か間違っているのですか?これを行うより良い方法はありますか?なぜこのようなことが起こっていますか?

なぜですか?私はPythonパッケージの背後にあるコンセプトを完全に理解しているとは思えません。

mod = __import__('foo.bar', fromlist = ['some_module']) 

でも「foo.bar」の部分は、実行時に変更することができますこの方法:私はこれを行うための適切な方法があると信じて、彼らはJavaのパッケージと同等と思っていたので、

+3

エラーメッセージには何が表示されますか? – ewall

+2

'some_module'が既にインポートされています! – SilentGhost

答えて

7

some_modulemod.some_moduleとして入手できます。あなたが別の変数にしたい場合のgetattr使用:docsから

the_module = getattr(mod, 'some_module') 
0

Direct use of __import__() is rare, except in cases where you want to import a module whose name is only known at runtime.

しかし、ドット表記は動作するはずです:

mod = __import__('foo.bar.some_module') 
1
from foo.bar import * 

が悪いですこれはsome_moduleをグローバルスコープにインポートするためです。

あなたはを通して、あなたのモジュールにアクセスすることができるはずです:簡単に、このアプローチが機能することを実証することができ

import foo.bar 
mod = getattr(foo.bar, 'some_module') 

>>> import os.path 
>>> getattr(os.path, 'basename') 
<function basename at 0x00BBA468> 
>>> getattr(os.path, 'basename\n') 
Traceback (most recent call last): 
    File "<pyshell#31>", line 1, in <module> 
    getattr(os.path, 'basename\n') 
AttributeError: 'module' object has no attribute 'basename 
' 

P.S.あなたがまだあなたの種類のインポートステートメントを使用することに興味があるなら。あなたはevalが必要です

from foo.bar import * 
eval('some_module') 

明確にする:だけでなく、それはそれはevalとの組み合わせででも悪いことだ-import *を使用するように悪い習慣です。だからちょうどgetattrを使用して、それはあなたのような状況のために正確に設計されています。

+0

-1はeval()を推奨します。あなたが望むのは、グローバルスコープから値を探すだけで、常にglobals()['some_module']を使用してください。 –

+0

もう一度、あなたの説明のために+1してください。 getattr()は正しい答えです。 __import __()を使う必要があるなら、kurczakの答えを見てください。 –

+0

ああ、今、私は "この回答が編集されていない限り、変更するにはあまりにも古く投票しています。"私の謝罪 - コードブロックでeval()を見て、自動的に-1をクリックしました。 –

関連する問題