如果你想暗示運行後,所有的crawl_*
方法的方法,最簡單的解決方案可能是設置一個元類,以編程方式爲你包裝這些方法。開始這個問題,一個簡單的包裝功能:
import functools
def wrapit(func):
@functools.wraps(func)
def _(self, *args, **kwargs):
func(self, *args, **kwargs)
self.save_to_db()
return _
這是一個包裝func
一個基本的裝飾,呼籲 self.save_to_db()
調用func
後。現在,我們成立了元類 將編程應用此具體方法:
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)
這將遍歷在包裝類中的方法,尋找與crawl_
開始 方法名,並與我們的 包裝他們裝飾者功能。
最後,包裹類本身,它聲明Wrapper
作爲 元類:
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'
鑑於上述情況,我們得到以下行爲:
>>> 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
>>>
你可以看到我們的save_to_database
方法在crawl_1
和crawl_2
(但不是在this_is_not_wrapped
之後)的 之後被調用。
在Python 2.上述作品在Python 3,replase這樣:
class Wrapped (object):
__metaclass__ = Wrapper
隨着:
class Wrapped (object, metaclass=Wrapper):
你想要什麼發生如果'crawl_1 '拋出異常? – RoadieRich