2012-10-26 64 views
2

我想在不知道它的情況下版本化對象。python中的透明對象版本化

事情是這樣的:

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 

是否有這樣做的一個簡單的方法?

+1

你想在這裏完成什麼?爲什麼'foo.version()'改變了? – mgilson

+0

我認爲通過重寫'__setattr__'和'__delattr__'可以在調用時增加每個實例的計數器來實現接近此目的。但是,我很難想到這種情況真的很有用。 – senderle

+0

@mgilson因爲從版本1開始的'foo'已經更改了3次。 – Srg

回答

1
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 
+0

謝謝,這應該做的! – Srg

2

快速劈:

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 
+0

我喜歡這個清潔版,謝謝!這是一個好主意,最後打電話給超級C'tor嗎?爲什麼類範圍的'version'屬性? – Srg

+0

@Srg - 因爲如果您在其他'init'代碼之前沒有調用'Version .__ init __(self)',實例將沒有'version'。 – mgilson

+0

@Srg類範圍是我個人喜歡的,因爲它可以更明確地反省類(你可以'dir(cls)'並且看到所有的屬性而不必實例化它,像'epydoc'這樣的代碼文檔工具也不能顯示屬性if你只能在'__init__'中定義它們)。最後的'super()'調用是將'version'初始化爲一個對象屬性,所以你可以有'Versioned'類的多個版本,並且版本值不會混淆。 – Fabian

0

請看看https://github.com/swisscom/cleanerversion。如果我正確理解你的要求,它確實正是你要找的。

由於我們需要一個持久的解決方案,因此該模塊在Django上構建,允許將這些對象寫入任何Django支持的關係數據庫。