Modul aus Stringvariable importieren

Lesezeit: 5 Minuten

Ich arbeite an einer Dokumentation (persönlich) für die verschachtelte Matplotlib (MPL)-Bibliothek, die sich von MPLs eigenen bereitgestellten, von interessierten Submodulpaketen unterscheidet. Ich schreibe ein Python-Skript, von dem ich hoffe, dass es die Dokumentenerstellung aus zukünftigen MPL-Versionen automatisieren wird.
Ich habe interessierte Untermodule/Pakete ausgewählt und möchte ihre Hauptklassen auflisten, aus denen ich eine Liste generieren und verarbeiten werde pydoc

Das Problem ist, dass ich keinen Weg finden kann, Python anzuweisen, das Submodul aus der Zeichenfolge zu laden. Hier ist ein Beispiel dafür, was ich versucht habe:

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

.

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

.

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

Und hier ist ein 3-Wege-Vergleich der obigen Listen über pprint:

Geben Sie hier die Bildbeschreibung ein

Ich verstehe nicht, was geladen ist y Objekt – es ist Basis matplotlib plus etwas anderes, aber es fehlen Informationen, die ich wollte, und das sind Hauptklassen von matplotlib.text Paket. Es ist der obere blaue Teil auf dem Screenshot (x aufführen)

Bitte schlagen Sie Sphinx nicht als anderen Ansatz vor.

  • Können Sie erklären, warum Sie verwenden müssen __import__(str) eher als die Norm import Aussage?

    – dasselbe

    3. Januar 2012 um 21:53 Uhr

  • Das liegt daran, dass ich Listen verarbeite, deren Elemente MPL-Submodule sind, und ihre Methodenpfade erhalte

    – Theta

    3. Januar 2012 um 22:00 Uhr

  • @thesamet – komm schon – es gibt endlose Ideen, wo Sie diese Funktionalität wünschen würden. Wenn Sie eine Textkonfiguration von Bibliotheken haben, können Sie sie nach Namen laden, was mit der nicht ganz funktionieren würde import Aussage. Hier ein Anwendungsbeispiel: djangosnippets.org/snippets/3048

    – Tomasz Gandor

    12. Mai 2014 um 4:55 Uhr

Benutzer-Avatar
mzjn

Das __import__ Funktion kann etwas schwer zu verstehen sein.

Wenn Sie sich ändern

i = __import__('matplotlib.text')

zu

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

dann i wird darauf verweisen matplotlib.text.

In Python 2.7 und Python 3.1 oder höher können Sie verwenden importlib:

import importlib

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

Einige Notizen

  • Wenn Sie versuchen, etwas aus einem Unterordner zu importieren, z ./feature/email.pysieht der Code so aus importlib.import_module("feature.email")

  • Sie können nichts importieren, wenn es keine gibt __init__.py in dem Ordner mit der Datei, die Sie importieren möchten

  • importlib sollte auf pypi für < python2.7 verfügbar sein

    – Jeffrey José

    19. August 2012 um 12:12 Uhr

  • Für alle, die von Google hierher kommen. Beachten Sie, dass, wenn Sie versuchen, etwas aus einem Unterordner zu importieren (z. ./feature/email.py) sieht der Code so aus importlib.import_module("feature.email")

    – Seanny123

    6. Dezember 2013 um 7:13 Uhr

  • Denken Sie schließlich auch daran, dass Sie nichts importieren können, wenn es keine gibt __init__.py in dem Ordner mit der Datei, die Sie importieren möchten.

    – Seanny123

    6. Dezember 2013 um 7:31 Uhr

  • @mzjn Das ist für import moduleName wobei moduleName eine Zeichenfolge ist. Wie wäre es mit from moduleName import * ?

    – Name G VU

    30. Mai 2017 um 6:47 Uhr

  • Ich habe hier gerade eine Antwort auf meine Frage gefunden, falls jemand sie braucht stackoverflow.com/a/31306598/248616

    – Name G VU

    30. Mai 2017 um 7:54 Uhr

Benutzer-Avatar
Gecko

importlib.import_module ist das, wonach Sie suchen. Es gibt das importierte Modul zurück.

import importlib

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

Sie können danach auf alles im Modul zugreifen als mymodule.myclass, mymodule.myfunctionetc.

  • Eine Alternative ist imp.load_source(..) Verwendung der imp Modul wie in dieser Antwort vorgeschlagen stackoverflow.com/questions/67631/…

    – Jewgeni Sergejew

    8. Juni 2014 um 6:30 Uhr

  • @gecco Das ist für import moduleName wobei moduleName eine Zeichenfolge ist. Wie wäre es mit from moduleName import * ?

    – Name G VU

    30. Mai 2017 um 6:57 Uhr

  • Hat jemand die @NamGVU-Frage herausgefunden?

    – Schützenstein

    22. März um 23:05 Uhr

verbrachte einige Zeit damit, Module aus einer Liste zu importieren, und dies ist der Thread, der mich am meisten dorthin gebracht hat – aber ich habe die Verwendung von ___import____ nicht verstanden –

Hier erfahren Sie, wie Sie ein Modul aus einer Zeichenfolge importieren und dasselbe Verhalten wie beim einfachen Import erhalten. Und versuchen/außern Sie auch den Fehlerfall. 🙂

  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)

und ja, für Python 2.7> haben Sie andere Optionen – aber für 2.6< funktioniert dies.

Abgesehen von der Verwendung der importlib kann man auch verwenden exec Methode zum Importieren eines Moduls aus einer String-Variablen.

Hier zeige ich ein Beispiel für den Import der combinations Methode aus itertools Paket mit der exec Methode:

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)

Ausgabe:

(1, 2)
(1, 3)
(1, 4)
(2, 3)
(2, 4)
(3, 4)

Ich habe diese 3 nützlichen Funktionen entwickelt:

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

Und jedes Mal, wenn ich eine neue Instanz neu laden möchte, muss ich nur getInstance() wie folgt aufrufen:

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

Endlich kann ich alle Funktionen innerhalb der neuen Instanz aufrufen:

myInstance.aFunction()

Die einzige Besonderheit besteht hier darin, die Parameterliste (param1, param2, param3) Ihrer Instanz anzupassen.

Benutzer-Avatar
Serge Stroobandt

Modul automatisch installieren und aus Liste importieren

Das folgende Skript funktioniert sowohl mit Submodulen als auch mit Pseudo-Submodulen.

# PyPI imports
import pkg_resources, subprocess, sys

modules   = {'lxml.etree', 'pandas', 'screeninfo'}
required  = {m.split('.')[0] for m in modules}
installed = {pkg.key for pkg in pkg_resources.working_set}
missing   = required - installed

if missing:
    subprocess.check_call([sys.executable, '-m', 'pip', 'install', '--upgrade', 'pip'])
    subprocess.check_call([sys.executable, '-m', 'pip', 'install', *missing])

for module in set.union(required, modules):
    globals()[module] = __import__(module)

Tests:

print(pandas.__version__)
print(lxml.etree.LXML_VERSION)

1051200cookie-checkModul aus Stringvariable importieren

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy