문자열 변수에서 모듈 가져 오기


183

관심있는 서브 모듈 패키지가 제공하는 MPL 자체 라이브러리와 다른 MPL 라이브러리에 대한 문서 (개인용)를 작성하고 있습니다. 향후 MPL 릴리스에서 문서 생성을 자동화 할 Python 스크립트를 작성 중입니다.
관심있는 서브 모듈 / 패키지를 선택하고 목록을 생성하고 처리 할 기본 클래스를 나열하려고합니다.pydoc

문제는 파이썬이 문자열에서 하위 모듈을로드하도록 지시하는 방법을 찾을 수 없다는 것입니다. 내가 시도한 것의 예는 다음과 같습니다.

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목록) 에서 상단 파란색으로 표시됩니다.

스핑크스를 다른 접근법으로 제안하지 마십시오.


__import__(str)표준 import상태가 아닌 왜 사용해야하는지 설명 할 수 있습니까 ?
thesamet

내가 항목 MPL 서브 모듈입니다 목록을 처리하고 자신의 방법 경로를 얻을 것이다 때문이다
세타

9
@thesamet-c'mon-이 기능을 원하는 끝없는 아이디어가 있습니다. 라이브러리의 텍스트 구성이있는 경우 이름으로로드 할 수 있으며 import명령문 과 함께 작동하지 않습니다 . 다음은 사용의 예는 다음과 같습니다 djangosnippets.org/snippets/3048
토마스 Gandor

답변:


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대한 pypi에 사용 가능한해야한다 <python2.7
제프리 호세

50
Google에서 온 사람이라면 누구나. 하위 폴더 (예 ./feature/email.pyimportlib.import_module("feature.email")
:)

11
마지막으로, 가져 오려는 __init__.py파일이있는 폴더에 없으면 가져올 수 없습니다 .
Seanny123

3
@mzjn import moduleNamemoduleName이 string 인 곳입니다. 어때요 from moduleName import *?
Nam G VU

2
어느 하나가 필요한 경우 여기에 내 질문에 대한 그냥 발견 대답 stackoverflow.com/a/31306598/248616
남 G VU

68

importlib.import_module당신이 찾고있는 것입니다. 가져온 모듈을 반환합니다. (Python> = 2.7 또는 3.x에만 사용 가능) :

import importlib

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

그 후 모듈 mymodule.myclass등의 모든 것에 액세스 할 수 있습니다 .


대안은 이 답변에서 제안 된대로 모듈imp.load_source(..)사용하는imp 것입니다 stackoverflow.com/questions/67631/…
Evgeni Sergeev

5
@gecco import moduleNamemoduleName이 string 인 곳입니다. 어때요 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()

여기에서 유일한 특이 사항은 인스턴스의 매개 변수 목록 (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.