2012-01-09 7 views
41

文字列があります。たとえば、abc.def.ghi.jkl.myfile.mymethodです。 mymethodを動的にインポートするにはどうすればよいですか?ここでファイル内のメソッドを文字列から動的にインポートします。

は、私はそれについていった方法です:インポート個々のモジュールが全く必要とされている場合、私は疑問に思って

def get_method_from_file(full_path): 
    if len(full_path) == 1: 
     return map(__import__,[full_path[0]])[0] 
    return getattr(get_method_from_file(full_path[:-1]),full_path[-1]) 


if __name__=='__main__': 
    print get_method_from_file('abc.def.ghi.jkl.myfile.mymethod'.split('.')) 

編集:私はPythonバージョン2.6.5を使用しています。

答えて

-2

importlib(2.7+のみ)を使用してください。パイソン< 2.7を使用することができる__ import__組み込み方法について

+1

私は2.6.5を使用します。私はこのようにそれを使用します。 'from __future__'ということをすることはできますか? –

+5

いいえ、 '__future__'は言語機能用であり、新しいstdlibモジュール用ではありません。 – ThiefMaster

+1

上記の例のように、buit-in '__import__'を使用してください。それは2.5に戻って動作し、その前にキーワードはありません。 –

17

:パイソン> = 2.7または3.1追加されたimportlib.import_module便利な方法について

__import__('abc.def.ghi.jkl.myfile.mymethod', fromlist=['']) 

importlib.import_module('abc.def.ghi.jkl.myfile.mymethod') 

更新:コメントに従って更新バージョン(私は最後までインポートする文字列を読んでいないと私は方法という事実を逃し認めなければならないだけで、このようなあなたのモジュールをインポートしますモジュールモジュール自体をインポートしないべきである)

パイソン< 2.7:

mymethod = getattr(__import__("abc.def.ghi.jkl.myfile", fromlist=["mymethod"])) 

パイソン> = 2.7:

mymethod = getattr(importlib.import_module("abc.def.ghi.jkl.myfile"), "mymethod") 
+6

最初のパラメータは '__import __()'と 'importlib.import_module()'の両方で*モジュール名*でなければならないため、これらの解決策のどちらも動作しません。 –

+1

importlib.import_module( 'abc.def.ghi.jkl.myfile.mymethod')は、メソッドの "修飾された"名前ではなく、 "絶対または相対的な用語でインポートするモジュール"を指定する必要があるため機能しません。 – frm

+0

これは明らかに機能しません。__import__の最初のパラメータは文字列ではなく、モジュールでなければなりません。 –

21

個々のモジュールをインポートする必要はありません。それはfromlist引数あなたから名前をインポートするモジュールをインポートし、提供するのに十分である:あなたの例abc.def.ghi.jkl.myfile.mymethodについて

def import_from(module, name): 
    module = __import__(module, fromlist=[name]) 
    return getattr(module, name) 

を、

import_from("abc.def.ghi.jkl.myfile", "mymethod") 

としてこの関数を呼び出します(つまりモジュールレベルの機能に注意してください。

このような簡単な作業のために、importlibモジュールを使用する利点はありません。

+0

import_from()が正しい方向に私を指摘しました。 'myClass = getattr(__ import __(" module.to.import "、fromlist = [" myClassName "])、" myClassName ")'です。助けてくれてありがとう! – Fydo

+1

'__import__'アプローチが有効です。しかし、 'help(__ import __)'を実行してみてください。 "この関数はPythonインタプリタで使用するためのものであり、汎用的なものではないので、プログラムを使ってモジュールをインポートするためには、' importlib.import_module() 'を使うのが良いでしょう。 – twasbrillig

+2

@twasbrillig:私がこの質問に答えたとき、Python 2.5と2.6は依然として広く使われていました。今日では、代わりに 'importlib'を使うのが最善です。 –

57

Python 2.7から、importlib.import_module()関数を使用できます。私の記憶ならば、私はこれにする傾向がある道(ならびに鉄塔やペーストなどの他のライブラリの数を

from importlib import import_module 

p, m = name.rsplit('.', 1) 

mod = import_module(p) 
met = getattr(mod, m) 

met() 
+0

Pythonのドキュメントには、 '__import __()'の上に 'importlib.import_module()'を使用することをお勧めします:https://docs.python.org/2/library/functions.html#__import__ - 2.7+。 – BoltzmannBrain

+2

'import_module' ** + **' rsplit' ** = **真の1つの道._ –

0

:あなたはモジュールをインポートし、次のコードで、その中に定義されたオブジェクトにアクセスすることができますモジュール名と関数/属性名の間に ':'を使用してモジュール名を区切ります。次の例を参照してください:

'abc.def.ghi.jkl.myfile:mymethod'

これは、使用する少し下のimport_from(path)機能が容易になります。

def import_from(path): 
    """ 
    Import an attribute, function or class from a module. 
    :attr path: A path descriptor in the form of 'pkg.module.submodule:attribute' 
    :type path: str 
    """ 
    path_parts = path.split(':') 
    if len(path_parts) < 2: 
     raise ImportError("path must be in the form of pkg.module.submodule:attribute") 
    module = __import__(path_parts[0], fromlist=path_parts[1]) 
    return getattr(module, path_parts[1]) 


if __name__=='__main__': 
    func = import_from('a.b.c.d.myfile:mymethod') 
    func() 
+1

どうしてこのことをしなければならないのですか?これには、呼び出し元がコロンでモジュール名と属性名を結合する必要があり、関数をコロンで再分割する必要があります。最初に2つのパラメータを使用するのはなぜですか? –

+0

設定ファイル(.yaml、.iniなど)を使用してフレームワークからアプリケーションにコールバックを接続すると、これが起こることがよくあります。次に、構成ファイル内の単一の文字列を使用して、フレームワークが呼び出す関数などを指定できます。 –

+0

さて、ええ、設定ファイルの構文としてこれを選択したいかもしれません。しかし、これはOPの質問にどのように関連していますか? (そして私がこれを自分の設定ファイルの構文として選んだとしても、設定ファイルのパーサでランダムなAPI関数ではなく解析したいと思っています) –

3

ローカルの名前空間に何をしようとしているのかは不明です。 my_methodをローカルに入力してoutput = my_method()と入力するとしますか?

# This is equivalent to "from a.b.myfile import my_method" 
the_module = importlib.import_module("a.b.myfile") 
same_module = __import__("a.b.myfile") 
# import_module() and __input__() only return modules 
my_method = getattr(the_module, "my_method") 

# or, more concisely, 
my_method = getattr(__import__("a.b.myfile"), "my_method") 
output = my_method() 

あなただけのローカル名前空間にmy_methodを追加しながら、あなたはモジュールのチェーンをロードしません。インポートの前後にあるsys.modulesのキーを見て変更を見ることができます。私はこれがあなたの他の答えよりも明確で、より正確であることを願っています。

完全性のために、チェーン全体を追加する方法です。あなたが__import__()を使用していて、プログラムが起動した後、あなたがパスを検索変更した場合

# This is equivalent to "import a.b.myfile" 
a = __import__("a.b.myfile") 
also_a = importlib.import_module("a.b.myfile") 
output = a.b.myfile.my_method() 

# This is equivalent to "from a.b import myfile" 
myfile = __import__("a.b.myfile", fromlist="a.b") 
also_myfile = importlib.import_module("a.b.myfile", "a.b") 
output = myfile.my_method() 

そして、最後に、あなたは__import__(normal args, globals=globals(), locals=locals())を使用する必要があります。理由は複雑な議論です。

+0

'the_module'と' same_module'の最初の例が間違っていて、異なる結果を生み出す。ダウン投票。 – sleepycal

0

このウェブサイトには素晴らしいソリューションがあります:load_class

foo = load_class(package.subpackage.FooClass)() 
type(foo) # returns FooClass 
1
from importlib import import_module 


name = "file.py".strip('.py') 
# if Path like : "path/python/file.py" 
# use name.replaces("/",".") 

imp = import_module(name) 

# get Class From File.py 
model = getattr(imp, "naemClassImportFromFile") 

NClass = model() # Class From file 
関連する問題