すべてのメンバー関数をパイデコレータで装飾できます。
@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と呼ばれるメソッドのみがトランザクションされます。