https://qiita.com/ganariya/items/fb3f38c2f4a35d1ee2e8
Um Python zu studieren, habe ich eine Group Intelligence Library namens acopy kopiert.
In acopy werden viele interessante Python-Grammatiken und -Sprachen verwendet, und es wird zusammengefasst, dass dies unter ihnen praktisch ist.
Dieses Mal konzentrieren wir uns darauf, die Ausführungsmethode dynamisch anhand des Variablennamens anzugeben.
getattr
In Python gibt es eine integrierte Funktion namens "getattr".
Sie können die Methode mit getattr (Instanz, Methodenname der Instanz) aus der Instanz abrufen.
Lassen Sie uns zunächst ein einfaches Beispiel versuchen.
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))
Schreiben wir einen einfachen Quellcode wie den oben genannten.
Instanz a wird aus Klasse A generiert
getattr (a, 'hello')
ruft die Methode des Hallo-Attributs der Instanz a ab.
Durch anschließendes Hinzufügen von () wird die extrahierte Methode tatsächlich ausgeführt.
Werfen wir einen Blick auf die tatsächliche Anwendung von getattr.
Dieses Mal haben Sie beschlossen, eine Klassenbibliothek namens Library zu erstellen. (Gerader Ball) In der Bibliothek wird eine eindeutige Verarbeitung von einer Funktion namens run ausgeführt, und interne Informationen werden vorerst in einer Mitgliedsvariablen namens "library_information" gespeichert.
Zu diesem Zeitpunkt haben Sie auch beschlossen, ein ** Plug-In ** zu verteilen, mit dem Sie anderen Benutzern, die die Bibliothek verwenden möchten, Zugriff auf die internen Informationen der Bibliothek gewähren.
Da es sich um eine von Ihnen erstellte Bibliothek handelt, können nur Sie den Hauptprozess implementieren. Durch Vorbereiten eines Prozesses zum Ausführen des Plug-Ins in der Ausführungsfunktion können Benutzer, die die internen Informationen der Bibliothek verwenden möchten, ihr eigenes Plug-In erstellen und weiter Es kann erweitert werden.
Schauen wir uns den Code an.
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 (Implementierung weggelassen)")
# 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 (Implementierung weggelassen)
20
Library main process (Implementierung weggelassen)
20
Library main process (Implementierung weggelassen)
20
30
'''
Bibliothek ist eine Bibliothek, die Sie auf PyPI usw. erstellen und veröffentlichen möchten. Beachten Sie beispielsweise Numpy und Matplotlib.
Ich wollte in den internen Informationen der Bibliothek etwas namens "library_information" vorbereiten, damit es von Drittbenutzern verwendet und erweitert werden kann. ** Bereiten Sie daher ein Plug-In-Array als Mitgliedsvariable vor, erben Sie die Plug-In-Klasse und übergeben Sie sie an add_plugin, damit das Plug-In ausgeführt werden kann. Wenn das Plugin aus der Bibliothek ausgeführt wird, werden die internen Informationen der Bibliothek übergeben, sodass der Benutzer die Funktion erweitern kann. ** ** **
Dieses Mal wird es mit print implementiert, aber ursprünglich ist es eine abstrakte Klasse, und Sie erstellen auch dieses Plugin, und der Benutzer erstellt das ursprüngliche Plugin, indem er dieses Plugin weiter erbt.
Durch Vorbereiten einer call- Funktion können Sie sie wie eine Funktion ausführen.
Verwenden Sie getattr, wenn Sie __call__
aufrufen.
Dies führt dazu, dass die Bibliotheksseite die Plugin-Instanz im Lauf ausführt und die Bibliotheksinformationen zu diesem Zeitpunkt weitergibt.
Dann ist die Plugin-Instanz getattr, die die Funktion herausbringt, die dem entsprechenden Hook "Start, Ende, Iteration" im Lauf entspricht, und sie verwendet.
Im Funktionslauf können Sie auch getattr wie call_plugins_start, call_plugins_finish löschen und alle Fälle separat schreiben. Auf diese Weise können Sie jedoch einheitlich schreiben.
Indem Sie eine Plug-In-Klasse zusammen mit der Bibliothek vorbereiten und an Benutzer verteilen
--Leiten Sie die Informationen in der Bibliothek von der Bibliotheksseite zum Plug-In weiter
Es gibt Vorteile. Beachten Sie jedoch, dass das Risiko von Laufzeitfehlern zunimmt, da Sie erst dann wissen, ob es korrekt ist, wenn Sie es ausführen.
Recommended Posts