105

私は文字列を持っています、言います: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を使用しています。

4

9 に答える 9

121

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()
于 2012-01-09T14:51:01.100 に答える
35

個々のモジュールをインポートする必要はありません。名前をインポートしたいモジュールをインポートしてfromlist引数を与えるだけで十分です:

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

あなたの例abc.def.ghi.jkl.myfile.mymethodでは、この関数を次のように呼び出します

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

(モジュール レベルの関数は、Python ではメソッドではなく関数と呼ばれることに注意してください。)

このような単純なタスクでは、importlibモジュールを使用する利点はありません。

于 2012-01-09T14:39:26.213 に答える
30

Python < 2.7 の場合、組み込みメソッド__ import__を使用できます。

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

Python >= 2.7 または 3.1 の場合、便利なメソッドimportlib.import_moduleが追加されました。次のようにモジュールをインポートするだけです。

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

更新:コメントに従って更新されたバージョン(最後までインポートする文字列を読んでおらず、モジュール自体ではなくモジュールのメソッドをインポートする必要があるという事実を見逃していたことを認めなければなりません)

Python < 2.7 :

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

Python >= 2.7:

mymethod = getattr(importlib.import_module("abc.def.ghi.jkl.myfile"), "mymethod")
于 2012-01-09T14:37:25.690 に答える
12

ローカル名前空間に対して何をしようとしているのかは不明です。私はあなたがちょうど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インポート前後のキーを見ることで変化を見ることができます。これが他の回答よりも明確で正確であることを願っています。

完全を期すために、これがチェーン全体を追加する方法です。

# 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__()していて、プログラムの起動後に検索パスを変更した場合は、 を使用する必要がある場合があります__import__(normal args, globals=globals(), locals=locals())。その理由は複雑な議論です。

于 2013-06-07T04:50:50.537 に答える
0

使用しますimportlib(2.7+ のみ)。

于 2012-01-09T14:35:34.340 に答える
-1

私がこれを行う傾向がある方法 (私の記憶が正しければ、pylons や paste などの他の多くのライブラリと同様) は、モジュール名と関数/属性名を「:」で区切ることです。 . 次の例を参照してください。

'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()
于 2012-01-09T15:13:53.907 に答える