python - 跟踪 python 中列表和字典的更改?

标签 python

我有一个类,该类的实例需要跟踪对其属性的更改。

示例:obj.att = 2 可以通过简单地覆盖 obj__setattr__ 来轻松跟踪。

但是,当我要更改的属性是一个对象本身时,如列表或字典,就会出现问题。

我如何才能跟踪 obj.att.append(1)obj.att.pop(2) 之类的东西?

我正在考虑扩展列表或字典类,但是一旦 objobj.att 都被初始化,猴子就会修补这些类的实例,这样当 .append 被调用时,obj 会收到通知。不知何故,这感觉不太优雅。

我能想到的另一种方法是将 obj 的实例传递到列表初始化中,但这会破坏很多现有代码,而且它看起来甚至不如以前的方法优雅。

还有其他想法/建议吗?我在这里缺少一个简单的解决方案吗?

最佳答案

当我看到这个问题时,我很好奇这是如何实现的,这是我想出的解决方案。不像我希望的那么简单,但它可能有用。首先,这是行为:

class Tracker(object):
    def __init__(self):
        self.lst = trackable_type('lst', self, list)
        self.dct = trackable_type('dct', self, dict)
        self.revisions = {'lst': [], 'dct': []}


>>> obj = Tracker()            # create an instance of Tracker
>>> obj.lst.append(1)          # make some changes to list attribute
>>> obj.lst.extend([2, 3])
>>> obj.lst.pop()
3
>>> obj.dct['a'] = 5           # make some changes to dict attribute
>>> obj.dct.update({'b': 3})
>>> del obj.dct['a']
>>> obj.revisions              # check out revision history
{'lst': [[1], [1, 2, 3], [1, 2]], 'dct': [{'a': 5}, {'a': 5, 'b': 3}, {'b': 3}]}

现在 trackable_type() 函数使这一切成为可能:

def trackable_type(name, obj, base):
    def func_logger(func):
        def wrapped(self, *args, **kwargs):
            before = base(self)
            result = func(self, *args, **kwargs)
            after = base(self)
            if before != after:
                obj.revisions[name].append(after)
            return result
        return wrapped

    methods = (type(list.append), type(list.__setitem__))
    skip = set(['__iter__', '__len__', '__getattribute__'])
    class TrackableMeta(type):
        def __new__(cls, name, bases, dct):
            for attr in dir(base):
                if attr not in skip:
                    func = getattr(base, attr)
                    if isinstance(func, methods):
                        dct[attr] = func_logger(func)
            return type.__new__(cls, name, bases, dct)

    class TrackableObject(base):
        __metaclass__ = TrackableMeta

    return TrackableObject()

这基本上使用元类来覆盖对象的每个方法,以便在对象更改时添加一些修订日志记录。这没有经过 super 彻底的测试,除了 listdict 之外,我还没有尝试过任何其他对象类型,但它似乎对那些工作没问题。

关于python - 跟踪 python 中列表和字典的更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8858525/

相关文章:

python - 检查 python 中的 Json 数据是否为 ​​none

python - 声音特征属性错误 : 'rmse'

Python 2.7 (urllib2)。如何使用 SSL HTTPS 代理?

python - 如何在 pandas 中进行复杂的数据清理

python - UnicodeEncodeError : 'ascii' codec can't encode character [. ..]

c++ - 在C++工作之后如何在Python中思考?

python - 如何减少内存使用并加快代码速度

python - 如何在 Pandas 数据框中显示特定数字

python - 无法在 Anaconda Python 3.6.4 Windows 10 中安装 Beautiful Soup

来自具有多列的 Pandas 数据框的 Python 散点图