首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有语句的Python :存储上下文

带有语句的Python :存储上下文
EN

Stack Overflow用户
提问于 2012-05-24 22:17:40
回答 2查看 370关注 0票数 2

我试图对下面的DataContext类进行改进(如果可能的话),或者找到其他解决方案:

代码语言:javascript
复制
class Store(object):

    def __init__( self, contents=None):
        self.contents = contents

class DataContext(object):

    def __init__( self, datastore ) : # datastore is of type store
        self.store = datastore

    def __enter__( self ) :
        self.temp_store = copy.copy( self.store.contents )  # Improve upon this!

    def __exit__( self, type, value, traceback ) :
        self.store.contents = self.temp_store

示例用法:

代码语言:javascript
复制
data = Store( [1,2,3] )
print "Before context: ", data.contents
with DataContext( data ):
    data.contents.append( 4 )         # Tampering with the data 
    print "Within context: ", data.contents

print "Outside context: ", data.contents

输出:

代码语言:javascript
复制
Before context:  [1, 2, 3]
Within context:  [1, 2, 3, 4]
Outside context:  [1, 2, 3]

对于大型数据结构,copy可能很昂贵。在exit期间,什么方法(或是否有)只在上下文中存储对数据结构的更改,然后撤消对数据的那些特定更改?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-24 22:32:35

你可以用一些检查点。例如,您可以保留一个单独的结构来插入新元素。退出上下文时,需要从容器中删除这些新元素。

显然,这与深度合作相比是否值得,将取决于以下几个因素:

  1. 是底层容器。并不是所有的API都有相同的API,因此您需要专门针对不同的受支持容器类型(这可能不是简单的)指定检查点机制。
  2. 输入上下文之前的元素比率与在上下文中插入的元素数之间的比率是多少。

此外,在正确性方面,容器的类型也会影响这种机构的设计。例如,如果容器是一个列表,则需要删除在上下文中插入的所有元素。另一方面,如果容器是一个集合,则只需要在它们最初不存在时才需要删除它们。

为了简单起见,让我们假设您只对列表感兴趣,只支持append操作,那么一个可能的解决方案实际上非常容易:

类DataContext(对象):

代码语言:javascript
复制
def __init__( self, datastore ) : # datastore is of type store
    self.store = datastore
    self.num_added = 0

def __enter__( self ) :
    pass

def __exit__( self, type, value, traceback ) :
    l = len(self.store.contents)
    del self.store.contents[l - self.num_added : l]

def append( self, elem ) :
    self.store.contents.append(elem)
    self.num_added += 1

当然,这是一个非常简单的情况,只是为了添加对从列表中的任何位置删除元素的支持,您需要对列表上执行的操作保持某种日志。日志可以是指定操作类型(插入、删除)及其参数(例如索引、数据)的条目列表。此外,您还需要使用代理或包装器来拦截列表上的每个修改操作(例如,appendextendinsertremove等)。如果您想支持所有的列表操作。

如果您想变得更通用,并且不仅支持列表,而且支持其他类型的容器,那么您将需要包装器来处理不同容器的操作。例如,对于set,您需要支持addremoveupdateintersection_update等。要做到这一点,您可以创建一个从DataContext降下来的类层次结构,并对每个类型进行专门的操作。

无论如何,正如您所看到的,实现这一点的复杂性会显著增加,这取决于您希望成为多少泛型。因此,如果您只想要为列表量身定做的特定解决方案,那么实现它可能会有回报,否则只需支付执行容器副本的代价即可。

票数 1
EN

Stack Overflow用户

发布于 2012-05-25 06:52:56

您可以使用数据库作为底层存储来实现Store,只需使用ROLLBACK

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10746067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档