2013-03-13 15 views
7

私はいくつかの異なるモジュールを持っている、と私は例えば、異なる状況に応じて、それらのいずれかをインポートする必要があります。pythonでモジュールを選択的にインポートするには?

if check_situation() == 1: 
    import helper_1 as helper 
elif check_situation() == 2: 
    import helper_2 as helper 
elif ... 
    ... 
else: 
    import helper_0 as helper 

これらのヘルパーは同じ辞書dict01dict02dict03が含まれている...しかしであることを、異なる値を持っています別の状況で呼ばれる。

  1. インポート文は、すべてのファイルの先頭に書かれているが、それは今までのところ、トップからだようcheck_situation()機能は、ここでの前提条件を必要とします:

    は、しかし、これはいくつかの問題があります。

  2. 1つ以上のファイルがこのヘルパーモジュールを必要とするので、この種のインポートを使用するのは難しくて醜いです。

これらのヘルパーの再配置方法は?

答えて

1

はそれを自分で解決、@Michaelスコット・カスバートに

# re_direct.py 

import this_module 
import that_module 

wanted = None 


# caller.py 
import re-direct 

''' 
many prerequisites 
''' 
def imp_now(case): 
    import re_direct 
    if case1: 
     re_direct.wanted = re_direct.this_module 
    elif case2: 
     re_direct.wanted = re_direct.that_module 

を参照さ呼び出し側であれば、そのimp_now、th呼び出し元のファイルやこれを呼び出す他のファイルで呼び出されても、this_or_that_moduleにすべてリダイレクトされます。

また、関数内でのみre_directをインポートするため、このモジュールは他の場所では表示されませんが、必要な場合のみ表示されます。

+0

これは、すべてのモジュールのコードをロードすることに注意してください。 –

+0

また、 'wanted'をインポートすると' re_direct.wanted'からそれを割り当てることで変更することはできません。インポートのリダイレクトはここではまったく必要ありません。 @DavideR。 –

+0

。はい、私はそれがまだうまくいきません。私はすべてのモジュールを読み込んでも構わないし、それ以上変更することはできない。次に、すべての発信者にthis_moduleまたはthat_moduleをインポートさせるにはどうすればよいですか? – ThunderEX

4

あなたは__import__()を使用することができ、それは文字列を受け取り、モジュールという返す:

helper=__import__("helper_{0}".format(check_situation())) 

例:

In [10]: mod=__import__("{0}math".format(raw_input("enter 'c' or '': "))) 
enter 'c' or '': c    #imports cmath 

In [11]: mod.__file__ 
Out[11]: '/usr/local/lib/python2.7/lib-dynload/cmath.so' 

In [12]: mod=__import__("{0}math".format(raw_input("enter 'c' or '': "))) 
enter 'c' or '': 

In [13]: mod.__file__ 
Out[13]: '/usr/local/lib/python2.7/lib-dynload/math.so' 

としては__import__()に@wimによっておよびpython3.xのドキュメントからの指摘:

モジュールをインポートします。この関数はPython インタプリタで使用するためのものであり、一般的な用途ではないため、プログラムでモジュールをインポートするには、 importlib.import_module()を使用する方がよいでしょう。

+2

-1 __import__' 'のドキュメント文字列読み取るため - _ _「この機能はPython インタプリタにより使用するためのものではなく、一般的な使用のために、プログラムモジュールをインポートする importlib.import_module()を使用することをお勧めしている」を – wim

+0

また、 "問題の背後にある問題"、つまりOPが変数名のデータを使用しているとみなされています。 – wim

+0

@wim私はdocstringやdocsで同じことを見つけることができません。 docs:*この関数はimport文によって呼び出されます。実行時に名前だけが分かっているモジュールをインポートしたい場合を除いて、__import __()を直接使用することはまれです。* –

3

まず、import文をファイルの先頭に置く必要があるという厳しい要件はありません。それはもっとスタイルガイドのことです。

は今、 importlibdictあなた if/ elifチェーンを交換するために使用することができます:

import importlib 

d = {1: 'helper_1', 2: 'helper_2'} 
helper = importlib.import_module(d.get(check_situation(), 'helper_0')) 

をしかし、それは本当にただ糖衣構文ですが、私はあなたが稚魚に大きな魚を持っている疑いがあります。あなたのデータ構造を再考し、コードを再設計する必要があるように思えます。あなたはdict01のような名前の変数を持ってい

いつでも、dict02dict03それはあなたがギアアップのレベルに必要な確かな証拠である、とdicts例えばいくつかのコンテナを持っていますそれらのリストあなたの 'ヘルパー'モジュール名は数字で終わります。

+0

はい本当に再設計が必要だと思う。元のスクリプトとして、もし私がちょうどhelper.dictA、ヘルパー。どのようにこの効果を達成するには? – ThunderEX

+0

モジュール内で、別のヘルパーモジュールの 'my_dict = dictA'と他のヘルパーモジュールの' my_dict = dictB'のエイリアスを付けることができます。その後、 'helper.my_dict'でアクセスしてください。しかし、これは技術的な問題を解決するものであり、設計上の問題ではないことを強調しなければならない。 – wim

1

他の回答に示されているアプローチは、あなたのタイトルにある主要な質問に近いですが、モジュールを読み込む際のオーバーヘッドが低い(辞書をいくつかインポートする可能性が高い)この場合には、輸入への影響、あなたがそれらすべてをインポートし、後でモジュール内の適切な辞書を選択したほうが良いことがあります。

import helper_0 
import helper_1 
... 
helperList = [helper_0, helper_1, helper_2...] 
... 
helper = helperList[check_situation()] 
関連する問題