文字列変数からモジュールをインポートする


183

興味のあるサブモジュールパッケージによって、ネストされたmatplotlib(MPL)ライブラリのドキュメント(個人)を作成しています。私は将来のMPLリリースからのドキュメント生成を自動化することを望んでいるPythonスクリプトを書いています。
関心のあるサブモジュール/パッケージを選択し、それらのメインクラスを一覧表示して、そこからリストを生成して処理しますpydoc

問題は、文字列からサブモジュールをロードするようにPythonに指示する方法が見つからないことです。これが私が試した例です:

import matplotlib.text as text
x = dir(text)

i = __import__('matplotlib.text')
y = dir(i)

j = __import__('matplotlib')
z = dir(j)

そして、これがpprintによる上記リストの3つの方法の比較です:

ここに画像の説明を入力してください

yオブジェクトに何がロードされているのか理解できません-それはベースmatplotlibと何か他のものですが、それは私が欲しかった情報を欠いており、それはmatplotlib.textパッケージのメインクラスです。スクリーンショットの一番上の青い部分です(xリスト)

別のアプローチとしてSphinxを提案しないでください。


__import__(str)標準のimportstatemet ではなくなぜ使用する必要があるのか​​説明できますか?
thesamet

これは、MPLサブモジュールであるアイテムのリストを処理し、それらのメソッドパスを取得するためです
theta

9
@thesamet-こんにちは-この機能が欲しい無限のアイデアがあります。ライブラリーのテキスト構成がある場合、ライブラリーを名前でロードできますが、importステートメントでは十分に機能しません。次に使用例を示します。djangosnippets.org
Tomasz

回答:


279

この__import__機能は少しわかりにくいかもしれません。

変更した場合

i = __import__('matplotlib.text')

i = __import__('matplotlib.text', fromlist=[''])

次にiを参照しmatplotlib.textます。

Python 2.7およびPython 3.1以降では、以下を使用できますimportlib

import importlib

i = importlib.import_module("matplotlib.text")

いくつかのメモ

  • たとえばサブフォルダから何かをインポートしようとする./feature/email.pyと、コードは次のようになりますimportlib.import_module("feature.email")

  • インポート__init__.pyしようとしているファイルのあるフォルダーに何もない場合はインポートできません


3
importlib<python2.7のpypiで使用可能でなければなりません
Jeffrey Jose

50
グーグルから来ている人のために。サブフォルダー(たとえば./feature/email.py)から何かをインポートしようとすると、コードは次のようになることに注意してくださいimportlib.import_module("feature.email")
Seanny123

11
最後に、__init__.pyインポートしようとしているファイルのあるフォルダーにフォルダーがない場合は、何もインポートできないことにも注意してください。
Seanny123 2013

3
@mzjnこれはimport moduleName、moduleNameが文字列の場合に使用します。いかがfrom moduleName import *ですか?
Nam G VU 2017年


68

importlib.import_moduleあなたが探しているものです。インポートされたモジュールを返します。(Python> = 2.7または3.xでのみ使用可能):

import importlib

mymodule = importlib.import_module('matplotlib.text')

その後、モジュール内の何にでもアクセスできますmymodule.myclass



5
@geccoこれはimport moduleName、moduleNameが文字列の場合に使用します。いかがfrom moduleName import *ですか?
Nam G VU

6

リストからモジュールをインポートするのにしばらく時間を費やしました、そしてこれは私がそこまでの道のりのほとんどを得たスレッドです-しかし、私は___import____の使用を理解していませんでした-

文字列からモジュールをインポートし、インポートと同じ動作をする方法は次のとおりです。そして、エラーケースも試してください/除外します。:)

  pipmodules = ['pycurl', 'ansible', 'bad_module_no_beer']
  for module in pipmodules:
      try:
          # because we want to import using a variable, do it this way
          module_obj = __import__(module)
          # create a global object containging our module
          globals()[module] = module_obj
      except ImportError:
          sys.stderr.write("ERROR: missing python module: " + module + "\n")
          sys.exit(1)

はい、Python 2.7>の場合は他のオプションがありますが、2.6 <の場合は機能します。


1

私はこれら3つの便利な機能を開発しました:

def loadModule(moduleName):
    module = None
    try:
        import sys
        del sys.modules[moduleName]
    except BaseException as err:
        pass
    try:
        import importlib
        module = importlib.import_module(moduleName)
    except BaseException as err:
        serr = str(err)
        print("Error to load the module '" + moduleName + "': " + serr)
    return module

def reloadModule(moduleName):
    module = loadModule(moduleName)
    moduleName, modulePath = str(module).replace("' from '", "||").replace("<module '", '').replace("'>", '').split("||")
    if (modulePath.endswith(".pyc")):
        import os
        os.remove(modulePath)
        module = loadModule(moduleName)
    return module

def getInstance(moduleName, param1, param2, param3):
    module = reloadModule(moduleName)
    instance = eval("module." + moduleName + "(param1, param2, param3)")
    return instance

そして、新しいインスタンスをリロードしたいときはいつも、次のようにgetInstance()を呼び出さなければなりません:

myInstance = getInstance("MyModule", myParam1, myParam2, myParam3)

最後に、新しいインスタンス内のすべての関数を呼び出すことができます。

myInstance.aFunction()

ここでの唯一の特異性は、インスタンスのparamsリスト(param1、param2、param3)をカスタマイズすることです。


1

別に使用からimportlibいずれかを使用することもできexec、文字列変数からモジュールをインポートする方法。

ここでは、combinationsメソッドをitertools使用してパッケージからメソッドをインポートする例を示していますexec

MODULES = [
    ['itertools','combinations'],
]

for ITEM in MODULES:
    import_str = "from {0} import {1}".format(ITEM[0],', '.join(str(i) for i in ITEM[1:]))
    exec(import_str)

ar = list(combinations([1, 2, 3, 4], 2))
for elements in ar:
    print(elements)

出力:

(1, 2)
(1, 3)
(1, 4)
(2, 3)
(2, 4)
(3, 4)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.