python中的透明对象版本控制

python中的透明对象版本控制,python,versioning,Python,Versioning,我想在对象不知道的情况下对其进行版本设置 大概是这样的: class Versioned(object): ... def version(self): ... class Foo(Versioned): def __init__(self, a): self.a = a foo = Foo(123) assert foo.version() == 1 foo.a = 1 foo.a = 2 foo.a = 3 assert foo.vers

我想在对象不知道的情况下对其进行版本设置

大概是这样的:

class Versioned(object):
   ...
   def version(self):
       ...

class Foo(Versioned):

   def __init__(self, a):
      self.a = a

foo = Foo(123)
assert foo.version() == 1

foo.a = 1
foo.a = 2
foo.a = 3

assert foo.version() == 4
有没有一个简单的方法可以做到这一点

class Versioned(object):
    def __init__(self):
        self.version = 0
    def __setattr__(self, name, value):
        if name == 'version':
            object.__setattr__(self, 'version', value)
        else:
            object.__setattr__(self, name, value)
            object.__setattr__(self, 'version', self.version +1)
例如:

class Foo(Versioned):
    pass

f = Foo()
print f.version  # prints 0

f.a = 1
print f.version # prints 1

f.b = 3
print f.version # prints 2

f.b = 33
print f.version # prints 3
快速破解:

class Versioned(object):
    version = 0

    def __init__(self):
        self.version = 0

    def _increaseVersion(self):
        super(Versioned, self).__setattr__('version', self.version+1)

    def __setattr__(self, attr, value):
        super(Versioned, self).__setattr__(attr, value)
        self._increaseVersion()

    def __delattr__(self, attr):
        super(Versioned, self).__delattr__(attr)
        self._increaseVersion()


class Foo(Versioned):
    def __init__(self, a):
        self.a = a
        super(Foo, self).__init__()


foo = Foo(123)
print 'value:', foo.a
print 'version:', foo.version
foo.a = 23
print 'value:', foo.a
print 'version:', foo.version
del foo.a
print hasattr(foo, 'a')
print 'version:', foo.version
产出:

value: 123
version: 1
value: 23
version: 2
False
version: 3
请看一看。如果我正确理解了您的需求,它将完全满足您的需求


由于我们需要某种持久性的解决方案,因此该模块建立在Django之上,它允许将这些对象写入任何Django支持的关系数据库。

您在这里想要实现什么?为什么
foo.version()。然而,我很难想象这样做会真正有用。@mgilson,因为从版本1开始的
foo
,已经更改了3次。@senderle,当有多个更改源时,版本控制可能非常有用:)@Srg——那么更改对象的函数呢?这些突变是按每个函数调用1个版本计算,还是按每个属性更改1个版本计算?还有,可变对象呢?如果在列表中添加内容,是否要增加版本计数器?我喜欢这个更干净的版本,谢谢!最后打电话给super c'tor是个好主意吗?为什么要使用类作用域
version
属性?@Srg——因为如果不调用
version,实例就不会有
version
。\uuuu init(self)
在其他
init
code之前。@Srg类作用域是我个人的爱好,因为它使类的内省更加明确(您可以
dir(cls))
可以查看所有属性,而不必实例化它,而且如果您仅在
中定义属性,那么像
epydoc
这样的代码文档工具将无法显示属性。最后的
super()
调用将
version
初始化为对象属性,这样您就可以对
version
类进行多个版本的控制,并且版本值不会混淆。