Importieren / laden Sie Module, die sich in Python geändert haben, dynamisch

Dies ist ein Beispiel für die Überwachung eines bestimmten Verzeichnisses und das Importieren / Neuladen, wenn ein Python-Modul erstellt / aktualisiert wird.

Weise

Dateiüberwachung

Die Dateiüberwachung ist nicht unmöglich selbst zu implementieren, kann jedoch mithilfe einer vorhandenen Bibliothek problemlos erreicht werden.

Hier verwenden wir ein Modul namens watchdog. Sie können Watchdog verwenden, um Ereignisse wie das Erstellen / Aktualisieren / Löschen von Dateien in einem bestimmten Verzeichnis zu erkennen.

Dynamischer Import von Modulen

Normalerweise verwenden Sie die import-Anweisung, um ein Modul zu importieren, aber Sie können den Modulnamen nicht als Zeichenfolge angeben.

Wenn Sie das zu importierende Modul dynamisch mit einer Zeichenfolge angeben möchten, verwenden Sie das Standardmodul impotlib.import_module (). Machen.

Der Modulname kann in der import-Anweisung nicht als Zeichenfolge angegeben werden


>>> import 'sys'
  File "<stdin>", line 1
    import 'sys'
               ^
SyntaxError: invalid syntax

importlib.import_module()Geben Sie dann den Modulnamen als Zeichenfolge an


>>> import importlib
>>> importlib.import_module('sys')
>>> sys = importlib.import_module('sys')
>>> sys
<module 'sys' (built-in)>

Modul neu laden

Das Aktualisieren der Python-Datei für ein importiertes Modul wird im laufenden Programm nicht berücksichtigt. Selbst wenn Sie die import-Anweisung oder impotlib.import_module () erneut ausführen, wird dies nicht wiedergegeben.

Verwenden Sie importlib.reload (), um das importierte Modul neu zu laden.

python


>>> with open('a.py', 'w') as f:
...     f.write('def f():\n    print("1")')
...
23
>>> import a
>>> a.f()
1
>>> with open('a.py', 'w') as f:
...     f.write('def f():\n    print("2")')
...
23
>>> a.f()
1
>>> import a
>>> a.f()
1
>>> import importlib
>>> a = importlib.import_module('a')
>>> a.f()
1
>>> a = importlib.reload(a)
>>> a.f()
2

Beispielcode

Funktioniert mit Python 3.4 und höher.

plugin_manager.py


import sys
import time
from importlib import import_module, reload
from pathlib import Path

from watchdog.events import FileSystemEvent, PatternMatchingEventHandler
from watchdog.observers import Observer


class PluginManager:

    class Handler(PatternMatchingEventHandler):

        def __init__(self, manager: 'PluginManager', *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.manager = manager

        def on_created(self, event: FileSystemEvent):
            print(event)
            if event.src_path.endswith('.py'):
                self.manager.load_plugin(Path(event.src_path))

        def on_modified(self, event):
            print(event)

    def __init__(self, path: str):
        self.plugins = {}
        self.path = path
        self.observer = Observer()

        sys.path.append(self.path)

    def start(self):

        self.scan_plugin()

        self.observer.schedule(self.Handler(self, patterns='*.py'), self.path)
        self.observer.start()

    def stop(self):
        self.observer.stop()
        self.observer.join()

    def scan_plugin(self):
        for file_path in Path(self.path).glob('*.py'):
            self.load_plugin(file_path)

    def load_plugin(self, file_path):
        module_name = file_path.stem
        if module_name not in self.plugins:
            self.plugins[module_name] = import_module(module_name)
            print('{} loaded.'.format(module_name))
        else:
            self.plugins[module_name] = reload(self.plugins[module_name])
            print('{} reloaded.'.format(module_name))


def main():

    plugin_manager = PluginManager('plugins/')
    plugin_manager.start()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        plugin_manager.stop()

if __name__ == '__main__':
    main()

Ausführungsergebnis

plugins/Zu einem.Beginnen Sie mit py


a loaded.

plugins/Zu b.Erstellen Sie py


<FileCreatedEvent: src_path='plugins/b.py'>
b loaded.
<DirModifiedEvent: src_path='plugins/'>
<DirModifiedEvent: src_path='plugins/__pycache__'>

b.Zu pyprint('bbb')Schreiben und speichern


<FileCreatedEvent: src_path='plugins/b.py'>
bbb
b reloaded.
<DirModifiedEvent: src_path='plugins/'>
<DirModifiedEvent: src_path='plugins/__pycache__'>

Ergänzung

Recommended Posts

Importieren / laden Sie Module, die sich in Python geändert haben, dynamisch
Importieren Sie Skripte dynamisch in Python
Importieren Sie Ihre eigenen Module mit der Python-Entwicklung von Grasshopper
Erstellen Sie in Python einen Dekorator, der Argumente dynamisch akzeptiert. Erstellen Sie einen Dekorator
Module, die die Shell in Python durchlaufen können
Rufen Sie Methoden in Python dynamisch auf
Arbeiten mit LibreOffice in Python: Importieren
Laden Sie JSON-Typen dynamisch mit Python
Importieren Sie ein Modul, das häufig beim Starten des Python-Interpreters verwendet wird
Definieren Sie Funktionen (Methoden) in Python dynamisch
Funktionen von Modulen für reguläre Ausdrücke, die in Python häufig persönlich verwendet werden
[Python3] Definieren Sie globale Variablen in einer Funktion dynamisch
Module und Pakete in Python sind "Namespaces"
Dynamisches Definieren von Variablen in Python
Beachten Sie, dass Python-Dekoratoren Wraps haben sollten
So füllen Sie mit Python dynamisch Nullen aus
Schreiben Sie mit f2py ein Python-Modul in fortran
Modulimport und Ausnahmebehandlung in Python
Importfehler: Kein Modul mit dem Namen 'xxxxx' in Python3
Ein Liner, der neunundneunzig in Python ausgibt
Zeichnen Sie Konturlinien, die in Lehrbüchern erscheinen (Python).
[Python] Ein Tool, das einen intuitiven relativen Import ermöglicht
Erstellen einer Umgebung, die Python mit Eclipse verwendet
Zusammenfassung zum Importieren von Dateien in Python 3
Beachten Sie, dass sich die Spezifikationen von Pandas loc geändert haben.
Ein Programm, das doppelte Anweisungen in Python entfernt
Dynamisches Ersetzen der nächsten Methode in Python
Statische Typprüfung, die in Python lose beginnt
Testmethoden, die zufällige Werte in Python zurückgeben
Unterschied in der Objekt-ID aufgrund des Imports in Python
Diejenige, die den Fortschrittsbalken in Python anzeigt
Import cv2 ModuleNotFoundError: Kein Modul mit dem Namen 'cv2' in Python3
Formeln, die unter Mathematik mit Python ausführen angezeigt werden
Beachten Sie, dass sich die Methode zum Veröffentlichen von Modulen in PyPI auf verschiedene Weise geändert hat.