Wenn Sie eine Methode wollen, nachdem alle Ihre crawl_*
Methoden implizit ausgeführt werden, ist die einfachste Lösung sein kann Richten Sie eine Metaklasse ein, die die Methoden für Sie programmatisch umschließt. Beginnen Sie mit diesem, eine einfache Wrapper-Funktion:
import functools
def wrapit(func):
@functools.wraps(func)
def _(self, *args, **kwargs):
func(self, *args, **kwargs)
self.save_to_db()
return _
, dass ein Grund Dekorateur ist die func
Wraps, ruft self.save_to_db()
nach func
aufrufen. Nun haben wir eine Metaklasse up, die diese spezielle Methoden programmatisch gelten:
class Wrapper (type):
def __new__(mcls, name, bases, nmspc):
for attrname, attrval in nmspc.items():
if callable(attrval) and attrname.startswith('crawl_'):
nmspc[attrname] = wrapit(attrval)
return super(Wrapper, mcls).__new__(mcls, name, bases, nmspc)
Diese über die Methoden in der umwickelten Klasse iterieren werden, für Methodennamen suchen, der mit crawl_
und Verpackung sie mit unserer starten Decorator-Funktion.
schließlich die verpackte Klasse selbst, die Wrapper
als metaclass erklärt:
class Wrapped (object):
__metaclass__ = Wrapper
def crawl_1(self):
print 'this is crawl 1'
def crawl_2(self):
print 'this is crawl 2'
def this_is_not_wrapped(self):
print 'this is not wrapped'
def save_to_db(self):
print 'saving to database'
die oben gegeben, so erhalten wir das folgende Verhalten:
>>> W = Wrapped()
>>> W.crawl_1()
this is crawl 1
saving to database
>>> W.crawl_2()
this is crawl 2
saving to database
>>> W.this_is_not_wrapped()
this is not wrapped
>>>
Sie können die unsere save_to_database
Methode sehen wird nach jeweils von crawl_1
und crawl_2
(aber nicht nach this_is_not_wrapped
) aufgerufen.
Die oben genannten Arbeiten in Python 2. In Python 3 replase dies:
class Wrapped (object):
__metaclass__ = Wrapper
mit:
class Wrapped (object, metaclass=Wrapper):
Was wollen Sie passieren wenn 'crawl_1 'löst eine Ausnahme aus? – RoadieRich