import copy
def Memento(obj, deep=False):
# 对你要做快照的对象做快照
state = (copy.copy if deep else copy.deepcopy)(obj.__dict__)
def Restore():
obj.__dict__ = state
return Restore
class Transaction:
deep = False
def __init__(self, *targets):
self.targets = targets
self.Commit()
# 模拟事务提交,其实就是初始化给每个对象往self.targets赋值
def Commit(self):
self.states = [Memento(target, self.deep) for target in self.targets]
# 回滚其实就是调用Memento函数,执行其中的闭包,将__dict__恢复
def Rollback(self):
for state in self.states:
state()
# 装饰器的方式给方法添加这个事务的功能
def transactional(method):
# 这里的self其实就是要保存的那个对象,和类的实例无关
def wrappedMethod(self, *args, **kwargs):
state = Memento(self)
try:
return method(self, *args, **kwargs)
except:
# 和上面的回滚一样,异常就恢复
state()
raise
return wrappedMethod
class NumObj(object):
def __init__(self, value):
self.value = value
def __repr__(self):
return '<%s: %r>' % (self.__class__.__name__, self.value)
def Increment(self):
self.value += 1
@transactional
def DoStuff(self):
# 赋值成字符串,再自增长肯定会报错的
self.value = '1111'
self.Increment()
if __name__ == '__main__':
n = NumObj(-1)
print n
t = Transaction(n)
try:
for i in range(3):
n.Increment()
print n
# 这里事务提交会保存状态从第一次的-1到2
t.Commit()
print '-- commited'
for i in range(3):
n.Increment()
print n
n.value += 'x' # will fail
print n
except:
# 回滚只会回顾到上一次comit成功的2 而不是-1
t.Rollback()
print '-- rolled back'
print n
print '-- now doing stuff ...'
try:
n.DoStuff()
except:
print '-> doing stuff failed!'
import traceback
traceback.print_exc(0)
pass
# 第二次的异常回滚n还是2, 整个过程都是修改NumObj的实例对象
print n
import Queue
import types
import threading
from contextlib import contextmanager
class ObjectPool(object):
def __init__(self, fn_cls, *args, **kwargs):
super(ObjectPool, self).__init__()
self.fn_cls = fn_cls
self._myinit(*args, **kwargs)
def _myinit(self, *args, **kwargs):
self.args = args
self.maxSize = int(kwargs.get("maxSize",1))
self.queue = Queue.Queue()
def _get_obj(self):
# 因为传进来的可能是函数,还可能是类
if type(self.fn_cls) == types.FunctionType:
return self.fn_cls(self.args)
# 判断是经典或者新类
elif type(self.fn_cls) == types.ClassType or type(self.fn_cls) == types.TypeType:
return apply(self.fn_cls, self.args)
else:
raise "Wrong type"
def borrow_obj(self):
# 这个print 没用,只是在你执行的时候告诉你目前的队列数,让你发现对象池的作用
print self.queue._qsize()
# 要是对象池大小还没有超过设置的最大数,可以继续放进去新对象
if self.queue.qsize()<self.maxSize and self.queue.empty():
self.queue.put(self._get_obj())
# 都会返回一个对象给相关去用
return self.queue.get()
# 回收
def recover_obj(self,obj):
self.queue.put(obj)
# 测试用函数和类
def echo_func(num):
return num
class echo_cls(object):
pass
# 不用构造含有__enter__, __exit__的类就可以使用with,当然你可以直接把代码放到函数去用
@contextmanager
def poolobj(pool):
obj = pool.borrow_obj()
try:
yield obj
except Exception, e:
yield None
finally:
pool.recover_obj(obj)
obj = ObjectPool(echo_func, 23, maxSize=4)
obj2 = ObjectPool(echo_cls, maxSize=4)
class MyThread(threading.Thread):
def run(self):
# 为了实现效果,我搞了个简单的多线程,2个with放在一个地方了,只为测试用
with poolobj(obj) as t:
print t
with poolobj(obj2) as t:
print t
if __name__ == '__main__':
threads = []
for i in range(200):
t = MyThread()
t.start()
threads.append(t)
for t in threads:
t.join(True)
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有