https://qiita.com/ganariya/items/fb3f38c2f4a35d1ee2e8
Afin d'étudier Python, j'ai copié une bibliothèque d'intelligence de groupe appelée acopy.
Dans acopy, de nombreuses grammaires et idiomes Python intéressants sont utilisés, et il est résumé que c'est pratique parmi eux.
Cette fois, nous nous concentrerons sur la spécification dynamique de la méthode d'exécution par nom de variable.
getattr
Il existe une fonction intégrée appelée getattr
en Python.
Vous pouvez récupérer la méthode de l'instance avec getattr (instance, nom de méthode de l'instance)
.
Pour l'instant, essayons un exemple simple.
class A:
def __init__(self, msg):
self.msg = msg
def hello(self):
print("hello ", self.msg)
def add(self, x, y):
return x + y
'''
hello world
7
'''
a = A("world")
getattr(a, 'hello')()
print(getattr(a, 'add')(2, 5))
Écrivons un code source simple comme celui ci-dessus.
L'instance a est générée à partir de la classe A
getattr (a, 'hello')
obtient la méthode de l'attribut hello de l'instance a.
Ensuite, en ajoutant () après cela, la méthode extraite est effectivement exécutée.
Jetons un coup d'œil à l'application réelle de getattr.
Cette fois, vous avez décidé de créer une bibliothèque de classes appelée Library. (Balle droite)
Dans la bibliothèque, un traitement unique est exécuté par une fonction appelée run, et les informations internes sont stockées dans une variable membre appelée library_information
pour le moment.
À ce stade, vous avez également décidé de distribuer un ** plug-in ** qui vous donne accès aux informations internes de la bibliothèque pour les autres utilisateurs qui souhaitent utiliser la bibliothèque.
Puisqu'il s'agit d'une bibliothèque que vous avez créée, vous seul pouvez implémenter le processus principal, mais en préparant un processus pour exécuter le plugin dans la fonction d'exécution, les utilisateurs qui souhaitent utiliser les informations internes de la bibliothèque peuvent créer leur propre plugin et plus Il peut être étendu.
Regardons en fait le code.
class Library:
def __init__(self):
self.plugins = []
self.library_information = {
'a': 10,
'b': 20,
'c': 30
}
def run(self):
# plugin start
self.call_plugins('start')
for cycle in range(3):
print("Library main process (Mise en œuvre omise)")
# plugin iteration
self.call_plugins('iteration')
# plugin finish
self.call_plugins('finish')
def call_plugins(self, hook):
for plugin in self.plugins:
plugin(hook, **self.library_information)
def add_plugin(self, plugin):
self.plugins.append(plugin)
class Plugin:
def __init__(self):
pass
def __call__(self, hook, **kwargs):
getattr(self, f'on_{hook}')(**kwargs)
def on_start(self, **kwargs):
print(kwargs['a'])
def on_iteration(self, **kwargs):
print(kwargs['b'])
def on_finish(self, **kwargs):
print(kwargs['c'])
library = Library()
library.add_plugin(Plugin())
library.run()
'''
10
Library main process (Mise en œuvre omise)
20
Library main process (Mise en œuvre omise)
20
Library main process (Mise en œuvre omise)
20
30
'''
La bibliothèque est une bibliothèque que vous souhaitez créer et publier sur PyPI, etc. Par exemple, soyez conscient de Numpy et Matplotlib.
Je voulais préparer quelque chose appelé «library_information» dans les informations internes de la bibliothèque afin qu'il puisse être utilisé et étendu par des utilisateurs tiers. Par conséquent, ** Préparez un tableau de plugins en tant que variable membre, héritez de la classe Plugin et transmettez-la à add_plugin afin que le plugin puisse être exécuté. Lorsque le plugin est exécuté à partir de la bibliothèque, les informations internes de la bibliothèque sont transmises, de sorte que l'utilisateur peut étendre la fonction. ** **
Cette fois, il est implémenté avec print, mais à l'origine, c'est une classe abstraite et vous créez également ce plugin, et l'utilisateur crée le plugin original en héritant davantage de ce plugin.
En préparant une fonction __call__
, vous pouvez l'exécuter comme une fonction.
Utilisez getattr lorsque vous appelez __call__
.
Cela amène le côté bibliothèque à exécuter l'instance de plug-in lors de l'exécution et à transmettre les informations de bibliothèque à ce moment-là.
Ensuite, l'instance de Plugin est getattr, qui fait ressortir la fonction qui correspond au hook start, finish, iteration
approprié dans l'exécution et l'utilise.
Dans la fonction exécutée, vous pouvez également supprimer getattr comme call_plugins_start, call_plugins_finish et écrire tous les cas séparément, mais cela vous permet d'écrire de manière unifiée.
En préparant une classe de plug-in avec la bibliothèque et en la distribuant aux utilisateurs
--Passez les informations de la bibliothèque du côté bibliothèque vers le plug-in
Il y a des avantages. Cependant, sachez que le risque d'erreurs d'exécution augmente car vous ne savez pas s'il est correct tant que vous ne l'exécutez pas.