你可以用一個餡餅裝飾器來裝飾每個成員函數,比如
@transaction
def insertData(self):
# code
和事務是一個裝飾器,您可以使用pre和post來定義函數。 是的,你必須爲每個功能做到這一點。這裏是一個例子
def transaction(f):
def pre():
print "pre transaction"
def post():
print "post transaction"
def wrapped(*args):
pre()
f(*args)
post()
return wrapped
class Foo(object):
def __init__(self):
print "instantiating"
def doFoo(self):
print "doing foo"
@transaction
def doBar(self, value):
print "doing bar "+str(value)
@transaction
def foofunc():
print "hello"
foofunc()
f=Foo()
f.doFoo()
f.doBar(5)
。
stefanos-imac:python borini$ python decorator.py
pre transaction
hello
post transaction
instantiating
doing foo
pre transaction
doing bar 5
post transaction
另一種方法就是使用一個元類,像這樣:
import types
class DecoratedMetaClass(type):
def __new__(meta, classname, bases, classDict):
def pre():
print "pre transaction"
def post():
print "post transaction"
newClassDict={}
for attributeName, attribute in classDict.items():
if type(attribute) == types.FunctionType:
def wrapFunc(f):
def wrapper(*args):
pre()
f(*args)
post()
return wrapper
newAttribute = wrapFunc(attribute)
else:
newAttribute = attribute
newClassDict[attributeName] = newAttribute
return type.__new__(meta, classname, bases, newClassDict)
class MyClass(object):
__metaclass__ = DecoratedMetaClass
def __init__(self):
print "init"
def doBar(self, value):
print "doing bar "+str(value)
def doFoo(self):
print "doing foo"
c = MyClass()
c.doFoo()
c.doBar(4)
這是純粹的黑魔法,但它的工作原理
stefanos-imac:python borini$ python metaclass.py
pre transaction
init
post transaction
pre transaction
doing foo
post transaction
pre transaction
doing bar 4
post transaction
通常你不想裝飾__init__
,並且您可能只想修飾具有特殊名稱的那些方法,因此您可能需要替換
for attributeName, attribute in classDict.items():
if type(attribute) == types.FunctionType:
的東西,如
for attributeName, attribute in classDict.items():
if type(attribute) == types.FunctionType and "trans_" in attributeName[0:6]:
這樣,只有調用的方法trans_whatever將transactioned。
不要打擾切片像這樣的字符串; 'str.startswith()'更具可讀性。 – Kevin