Python对象历史记录

2024-03-28 21:50:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图想出一种方法来跟踪对象在Python中的各种重新化身。例如,我想有一个班级,比如说,一个房间。这个房间可以开始作为一个“厨房”存在,然后,在任何特定的时间点,成为一个“书房”。我希望能够跟踪(或记录)我房间生活中的所有这些不同阶段。所以,我想出了这个办法,想知道有没有更好的办法。或者我错过了什么。不过,据我所知,它似乎对我的目的有效。在

class room():
    def __init__(self,current="Any", history = []):
        self.current = childroom(current)
        self.history = history
        self.history.append(self.current)

    def changeroom(self,current = "New"):
        self.current = childroom(current)
        self.history.append(self.current)


class childroom(room):
    def __init__(self,name="Any"):
        self.name = name    

当我使用这个代码时。。。在

^{pr2}$

Tags: 对象方法nameselfinitdefanycurrent
2条回答

这听起来像是facade模式的一个例子-拥有一个捕捉当前状态的interner room对象,并在facade上使用__setattr__来捕获分配,归档以前的状态(内部对象),并使用更新的属性值创建一个新的。您需要重写__getattr__以委托给内部对象,内部对象也将具有用于其他任何操作的适当方法。在

我个人会这样做:

#! /usr/bin/python3
import copy

class Room:
    def __init__ (self, state = 'Initial'):
        self.state = state
        self.history = []

    def morph (self, state):
        clone = copy.deepcopy (self)
        self.state = state
        self.history.append (clone)

请记住,我不知道您的实际设置是否有一些限制深度复制的功能。在

这就产生了:

^{pr2}$

我想通常你不需要保存对象的整个状态,只需要保存值得跟踪的属性。你可以按照以下思路将这种行为打包成一个装饰师:

#! /usr/bin/python3

import datetime
import copy

class Track:
    def __init__ (self, *args, saveState = False):
        self.attrs = args
        self.saveState = saveState

    def __call__ (self, cls):
        cls._track = []
        this = self

        oGetter = cls.__getattribute__
        def getter (self, attr):
            if attr == 'track': return self._track
            if attr == 'trackTrace': return '\n'.join ('{}: "{}" has changed to "{}"'.format (*t) for t in self._track)
            return oGetter (self, attr)
        cls.__getattribute__ = getter

        oSetter = cls.__setattr__
        def setter (self, attr, value):
            if attr in this.attrs:
                self._track.append ( (datetime.datetime.now (), attr, copy.deepcopy (value) if this.saveState else value) )
            return oSetter (self, attr, value)
        cls.__setattr__ = setter

        return cls

现在我们可以这样使用这个装饰器:

@Track ('holder')
class Book:
    def __init__ (self, title):
        self.title = title
        self.holder = None
        self.price = 8

class Person:
    def __init__ (self, firstName, lastName):
        self.firstName = firstName
        self.lastName = lastName

    def __str__ (self):
        return '{} {}'.format (self.firstName, self.lastName)

r = Book ('The Hitchhiker\'s Guide to the Galaxy')
p = Person ('Pedro', 'Párramo')
q = Person ('María', 'Del Carmen')
r.holder = p
r.price = 12
r.holder = q
q.lastName = 'Del Carmen Orozco'
print (r.trackTrace)

如果用@Track ('holder')调用,则会产生:

2013-10-01 14:02:43.748855: "holder" has changed to "None"
2013-10-01 14:02:43.748930: "holder" has changed to "Pedro Párramo"
2013-10-01 14:02:43.748938: "holder" has changed to "María Del Carmen Orozco"

如果使用@Track ('holder', 'price')调用,则会产生:

2013-10-01 14:05:59.433086: "holder" has changed to "None"
2013-10-01 14:05:59.433133: "price" has changed to "8"
2013-10-01 14:05:59.433142: "holder" has changed to "Pedro Párramo"
2013-10-01 14:05:59.433147: "price" has changed to "12"
2013-10-01 14:05:59.433151: "holder" has changed to "María Del Carmen Orozco"

如果用@Track ('holder', saveState = True)调用,则会产生:

2013-10-01 14:06:36.815674: "holder" has changed to "None"
2013-10-01 14:06:36.815710: "holder" has changed to "Pedro Párramo"
2013-10-01 14:06:36.815779: "holder" has changed to "María Del Carmen"

相关问题 更多 >