对于类中的所有函数,是否存在__enter __和__exit__等价物?

Nie*_*ein 4 python class function

蟒蛇的一个功能,我用的数据库(或文件)工作时发现了非常方便的是__enter____exit__功能,你可以给一个类.现在通过使用该with语句,您可以确保__enter__首先调用此块(并且可以打开数据库或文件),并在__exit__调用完成后调用(并且可以关闭数据库或文件.

每次调用我的Database类中的函数时,我想打开和关闭一个sqlite事务.我可以在每个函数的开头和结尾处执行它,但是因为必须为每个函数完成该类,我想知道,是否有在每个函数调用之前和之后调用的方法?像单元测试中的SetUp和TearDown一样.

Ste*_*ini 7

您可以使用饼图装饰器来装饰每个成员函数

@transaction
def insertData(self):
    # code
Run Code Online (Sandbox Code Playgroud)

和事务是一个装饰器,你定义用一个前置和后置包装函数.是的,您必须为每个功能执行此操作.这是一个例子

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)
Run Code Online (Sandbox Code Playgroud)

.

stefanos-imac:python borini$ python decorator.py 
pre transaction
hello
post transaction
instantiating
doing foo
pre transaction
doing bar 5
post transaction
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用元类,如下所示:

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)
Run Code Online (Sandbox Code Playgroud)

这是纯粹的黑魔法,但它的作用

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
Run Code Online (Sandbox Code Playgroud)

你通常不想装饰__init__,你可能只想装饰那些带有特殊名称的方法,所以你可能想要更换

        for attributeName, attribute in classDict.items():
            if type(attribute) == types.FunctionType:
Run Code Online (Sandbox Code Playgroud)

喜欢的东西

        for attributeName, attribute in classDict.items():
            if type(attribute) == types.FunctionType and "trans_" in attributeName[0:6]:
Run Code Online (Sandbox Code Playgroud)

这样,只有trans_whatever的方法才会被转换.