Importez / rechargez dynamiquement les modules qui ont changé dans Python

Ceci est un exemple de surveillance d'un répertoire spécifique et d'importation / rechargement lorsqu'un module Python est créé / mis à jour.

manière

Surveillance des fichiers

La surveillance des fichiers n'est pas impossible à mettre en œuvre par vous-même, mais elle peut être facilement réalisée en utilisant une bibliothèque existante.

Ici, nous utilisons un module appelé watchdog. Vous pouvez utiliser watchdog pour détecter des événements tels que la création / la mise à jour / la suppression de fichiers dans un répertoire spécifique.

Import dynamique de modules

Vous utilisez généralement l'instruction import pour importer un module, mais vous ne pouvez pas spécifier le nom du module sous forme de chaîne.

Si vous souhaitez spécifier dynamiquement le module que vous souhaitez importer avec une chaîne de caractères, utilisez le module standard impotlib.import_module (). Faire.

Le nom du module ne peut pas être spécifié sous forme de chaîne de caractères dans l'instruction d'importation


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

importlib.import_module()Spécifiez ensuite le nom du module sous forme de chaîne de caractères


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

Recharge du module

La mise à jour du fichier Python pour un module importé ne sera pas reflétée dans le programme en cours d'exécution. Même si vous exécutez à nouveau l'instruction import ou ʻimpotlib.import_module () `, cela ne sera pas reflété.

Utilisez importlib.reload () pour recharger le module importé.

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

Exemple de code

Fonctionne avec Python 3.4 et supérieur.

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()

Résultat d'exécution

plugins/À un.Commencez avec py


a loaded.

plugins/À b.Créer py


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

b.Pour pyprint('bbb')Ecrire et sauvegarder


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

Supplément

Recommended Posts

Importez / rechargez dynamiquement les modules qui ont changé dans Python
Importer dynamiquement des scripts en Python
Importez vos propres modules avec le développement Python de Grasshopper
En Python, créez un décorateur qui accepte dynamiquement les arguments Créer un décorateur
Modules pouvant passer par le shell en Python
Appeler dynamiquement des méthodes en Python
Travailler avec LibreOffice en Python: import
Charger dynamiquement les types json avec python
Importez un module souvent utilisé lors du démarrage de l'interpréteur python
Définir dynamiquement des fonctions (méthodes) en Python
Caractéristiques des modules d'expressions régulières qui sont souvent utilisés personnellement en Python
[Python3] Définir dynamiquement des variables globales dans une fonction
Les modules et packages en Python sont des "espaces de noms"
Comment définir dynamiquement des variables en Python
Notez que les décorateurs Python doivent avoir des wraps
Comment remplir dynamiquement des zéros avec Python
Ecrire un module python dans fortran en utilisant f2py
Importation de modules et gestion des exceptions en python
Erreur d'importation: aucun module nommé "xxxxxx" dans Python3
Une doublure qui produit quatre-vingt-dix-neuf en Python
Dessiner des lignes de contour qui apparaissent dans les manuels (Python)
[Python] Un outil qui permet une importation relative intuitive
Créer un environnement qui utilise Python avec Eclipse
Résumé de la façon d'importer des fichiers dans Python 3
Notez que les spécifications de Pandas loc ont changé.
Un programme qui supprime les instructions en double en Python
Pour remplacer dynamiquement la méthode suivante en python
Vérification de type statique qui démarre vaguement en Python
Méthodes de test qui renvoient des valeurs aléatoires en Python
Différence d'ID d'objet due à l'importation en Python
Celui qui affiche la barre de progression en Python
Importer cv2 ModuleNotFoundError: Aucun module nommé "cv2" dans python3
Formules qui apparaissent dans Faire des mathématiques avec Python
Notez que la méthode de publication des modules sur PyPI a changé de différentes manières.