2016-05-01 7 views
1

その名前を持つモジュールまたはそのファイル名からモジュールをインポートしたとしても、ファイル名からモジュールをロードして返すPythonルーチンを探しています。すべての条件(変更されたモジュール、変更されたファイル名)の下でファイル名からモジュールをインポートする

具体的には、私は次のテストに合格する機能unconditional_importを書きたい:

import os 

def make_module(folder, filename, version): 
    try: os.mkdir(folder) 
    except OSError: pass 

    f = open(os.path.join(folder,filename), "w") 
    f.write("version = %i" % version) 
    f.close() 

make_module("test","spam.py", 1) 
assert(unconditional_import("test","spam.py").version == 1) 

make_module("test","more_spam.py", 2) 
assert(unconditional_import("test","more_spam.py").version == 2) 

make_module("test","more_spam.py", 3) 
assert(unconditional_import("test","more_spam.py").version == 3) 

make_module("test2","more_spam.py", 4) 
assert(unconditional_import("test2","more_spam.py").version == 4) 

私は(私は構造化されたものを維持するための答えとして掲載します)、このための解決策を見つけたが、それはありますむしろ醜いですし、強く感じることもありません。私は、これをやるための簡単で自然な方法があると期待していますが、私はそれを見つけることができません。

注:

  • 私はHow to import a module given the full path?を認識してい、パスからモジュールをインポートする方法アドレス、一度だけ動作します。

  • 私はほとんどの場合、通訳者をリロードするだけですが、それは私の選択肢ではないことに気づいています。

    def unconditional_import(folder, filename): 
        full_path = os.path.join(folder,filename) 
    
        if os.path.isfile(full_path+"c"): 
         os.remove(full_path+"c") 
    
        cachefolder = os.path.join(folder,"__pycache__") 
        if os.path.isdir(cachefolder): 
         for f in os.listdir(cachefolder): 
          if f.startswith(filename.rstrip(".py")) and f.endswith(".pyc"): 
           os.remove(os.path.join(cachefolder,f)) 
    
        if sys.version_info < (3,0): 
         from imp import load_source 
         foo = load_source("foo", full_path) 
    
        elif sys.version_info < (3,5): 
         from importlib.machinery import SourceFileLoader 
         foo_module = SourceFileLoader("foo", full_path) 
         foo = foo_module.load_module() 
    
        else: 
         from importlib.util import spec_from_file_location, module_from_spec 
         spec = spec_from_file_location("foo", full_path) 
         foo = module_from_spec(spec) 
         spec.loader.exec_module(foo) 
    
        return foo 
    

    問題とノート:

+1

なぜこれが必要ですか。あなたは実際に何を達成しようとしていますか?そしてなぜ単にリロードしないのですか(http://stackoverflow.com/questions/1254370/reimport-a-module-in-python-while-interactiveを参照)? – jonrsharpe

+0

@jonrsharpe: 'reload'だけでは不十分です。私の答えを見てください:ファイル除去ルーチンを削除して(そして 'reload'に頼るだけで)、3番目のテストは失敗します。 - なぜ私はこれが必要なのか:終わりに、私はいくつかのジャストインタイムコンパイルを実装しようとしている(いいえ、Cythonなどはオプションではない)。しかしこれを説明することは、私の意見では質問。 – Wrzlprmft

+1

そのような情報がなければ、おそらく[XY問題](http://meta.stackexchange.com/q/66377)です。 – jonrsharpe

答えて

2

私の最善の解決策は、これまでである私は、Python 3.5以降でバリアントをテストすることができませんでした

  • が、私は理由を見ていませんなぜそれがうまくいかないのか、なぜ簡単な解決策があるのか​​。

  • 手動でPYCファイルを削除すると、私は気が狂ってしまい、問題が発生することが予想されます。

関連する問題