公开memento设计模式的python包

recollection的Python项目详细描述


回忆概述

回忆是一种状态回忆系统。它允许对象的状态 将快照功能公开,然后“回滚”到任何 以前存储的状态。

回忆给这一机制两个明显不同的曝光。如果 性能不是最关键的问题,您的重点是代码 简单,那么继承方法可能是您的最佳选择。 如果你拥有需要历史状态的类的所有权。

注意:这是当前的预发行版

安装

您可以使用pip:

pip install recollection

或者,您可以从以下位置获取源: https://github.com/mikemalinowski/recollection

回忆遗传(推断)

此示例演示如何使用继承来设置类 自动处理状态存储。从这个例子可以看出 在处理过程中,无需在任何时候明确要求记忆存储 完全为了你。此示例特别显示属性存储:

importrecollection# -- Inference is the recollection class designed specifically# -- for inheritance situations.classFoo(recollection.Inference):def__init__(self):super(Foo,self).__init__()self.number=10# -- Register 'number' as a property to monitorself.memento.register('number')# -- Instance our objectfoo=Foo()# -- Here we demonstrate directly changing properties# -- which are registeredfoo.number=5foo.number=99print(foo.number==99)# -- Now restore back one stepfoo.recollection.restore(1)print(foo.number==5)

而这个例子展示了如何使用decorators来存储方法 吸气机和二传机:

importrecollection# -- Inference is the recollection class designed specifically# -- for inheritence situations.classFoo(recollection.Inference):def__init__(self):super(Foo,self).__init__()self._number=10# -- Declare that this is a recollection getter@recollection.infer.get('number')defnumber(self):returnself._number# -- Declare this as a recollection setter@recollection.infer.store('number')defset_number(self,value):self._number=value# -- Instance our objectfoo=Foo()# -- Update our variable using our accessor fornumberinrange(10):foo.set_number(number)# -- Demonstrate that the current state is 'e'print(foo.number())# -- Prints 9# -- Roll back one step in the memento historyfoo.recollection.restore(1)print(foo.number())# -- Prints 8

纪念品堆

然而,我们并不总是有奢侈的改变阶级继承 或者你可能特别想把记忆状态管理排除在外 实际继承层次结构的。下面的例子都演示了 如何做到这一点。

在本例中,我们有一个具有两个属性的类。我们就是例子 针对我们的foo实例的memento类。每次我们打电话给 在memento中存储方法我们正在获取值的快照 由注册的属性/函数返回

importrecollectionclassFoo(object):def__init__(self):self.number=0# -- Instance our objectfoo=Foo()# -- Instance a memento object pointing at foomemento=recollection.Memento(foo)memento.register('number')# -- Start changing some values on foo, and# -- ask our stack to store those changesfornumberinrange(11):foo.number=number# -- Ask the memento object to store the statememento.store()# -- Printing i, shows us 10print(foo.number)# -- But lets say we roll back to the state 5 versions# -- agomemento.restore(5)# -- Now we can see i is at the version it was when# -- it was stored 5 versions backprint(foo.number)

锁定分级存储

它还允许将多个纪念品放入一个锁定步骤, 这样,每当一个纪念品对象正在存储或恢复时 同步组中的所有其他纪念品对象也将存储或 恢复。

importrecollectionclassFoo(object):def__init__(self):self.number=0# -- This time we instance two completely seperate# -- foo objectsfoo_a=Foo()foo_b=Foo()# -- Instance a memento stack for eachmemento_a=recollection.Memento(foo_a)memento_b=recollection.Memento(foo_b)memento_a.register('number')memento_b.register('number')# -- Now we will put our stacks into a state of lock-step# -- which means whenever one of them is stored or restored# -- all others in the lock-step group will have the same# -- action performedmemento_a.group(memento_b)# -- Increment some values on both objectsforiinrange(11):foo_a.i=ifoo_b.i=i# -- Trigger a store on only one stackmemento_a.store()# -- We can see that both A and B have a value of 10print(foo_a.i==10andfoo_b.i==10)# -- Now we rollback - knowing that this action will occur# -- across all grouped memento objectsmemento_a.restore(5)# -- Now we can see i is at the version it was when# -- it was stored 5 versions backprint(foo_a.i==5andfoo_b.i==5)

串行化

序列化程序也可以根据memento实例进行注册,允许 要序列化为持久性的memento对象的存储状态 国家。

这个例子展示了我们如何定义一个用户首选项类,以及 在该类中,我们定义一个memento对象来存储首选项 国家。通过注册序列化程序,将写入首选项状态 每当调用“store”时,都要进行磁盘操作。

注意,在本例中,我们还选择不存储私有 成员变量,但是我们使用 类作为getter和setter。

classUserPreferences(object):def__init__(self):# -- Visual preferencesself._theme='default'# -- Define our memento, which we utilise specifically to# -- store our preferences to a persistent locationself._memento=recollection.Memento(self)# -- We will utilise the JSON Appdata serialiser, which# -- writes our memento information to the app data system# -- locationself._memento.register_serialiser(serialiser=recollection.JsonAppSerialiser,identifier='memento/demos/userprefs/UserPreferenceA',)# -- Register which properties we want the store to focus onself._memento.register(label='theme',getter=self.get_theme,setter=self.set_theme,)# -- Finally, we deserialise - which will update this class# -- with any previously stored stateself._memento.deserialise()# --------------------------------------------------------------defget_theme(self):returnself._theme# --------------------------------------------------------------defset_theme(self,theme):self._theme=themeself._memento.store(serialise=True)

装饰

同样,如果我们想让它在课堂上更明显一点 我们可以选择使用纪念品装饰器来存储哪些功能, 哪些存储和序列化:

classUserPreferences(object):@recollection.serialise_after('theme')defset_theme(self,theme):self._theme=theme

示例

这些机制都在示例模块中演示,具体来说:

用户首选项对象

此演示显示正在交互的用户首选项对象 其工作方式与上述示例相同,其中 设置存储为已更改的传入-允许首选项 “撤销”。

# -- This demo shows a user preferences object being interacted# -- which which works in the same way as the example above.fromrecollection.examples.userprefs.demoimportdemodemo()

替代用户首选项对象

这个演示在输出方面与上面的演示相同,但是 通过装饰工处理。

fromrecollection.examples.userprefs.demoimportdemo2demo2()

带回滚功能的棋盘游戏

本演示使用“棋盘游戏”风格的场景,其中 我们有两个玩家想要“撤销”结果 如果不合意的话就轮换!

fromrecollection.examples.boardgame.gameimportdemodemo()

引脚移动(多属性改变)

这个演示展示了一个实际设置的setter的使用 多个记录的属性,但希望有一个还原步骤。

fromrecollection.examples.pins.demoimportdemodemo()

重命名程序(用户界面和代码)

这个演示展示了如何使用回忆来存储函数的状态 对象,表示为可视化工具(使用Pyside2)。

fromrecollection.examples.renamer.demoimportdemodemo()

测试和稳定性

目前有花絮覆盖了大部分纪念品的核心,但还没有穷尽。

相容性

这已经在ubuntu和windows上的python 2.7.13和python 3.6.6下进行了测试。

贡献

如果你想贡献思想,想法,修复或功能请联系!mike@twisted.space

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java错误:无法解析方法   如何用相同的父标记和子标记在Java中解析XML?   日期使用Java中的时区偏移将本地时间转换为UTC   java如何在多进程、多线程环境中读取文件   WebView中的java弹出式对话框不在当前显示范围内,但在chrome浏览器中运行良好   只有2个参数的java递归二进制搜索方法   无法在java中调用函数   java JavaMail在Tomcat服务器上运行时停止工作   反射通过java程序生成、编译和运行java类   java Android:如何使ListView即使在应用程序关闭后仍保持禁用状态   在JAVA中识别匿名类实例   java渲染一个由三角形组成的立方体,在旋转时会产生奇怪的角度   函数式编程如何基于比较连续的列表元素将Java流减少为布尔值   java如何替换列表中的多个项目?   java Android如何获取随机sqlite数据?   java我已经将useSSL设置为false,但仍然收到警告   java使用动态变量生成jlabel   apachespark:java。lang.NoClassDefFoundError v2TableWithV1回退