【问题标题】:Update history of Python object as dictionary and preserve first item将 Python 对象的历史更新为字典并保留第一项
【发布时间】:2019-04-01 12:05:05
【问题描述】:

我是课堂编程的新手。我正在尝试将我的对象的初始属性(这是一个字典)保存在其历史记录中,然后使用属性的更改更新历史记录。代码下方:

import datetime
import pytz

class Property:
    """ Simple property class """ 

    @staticmethod
    def _current_time():
        utc_time = datetime.datetime.utcnow()
        return pytz.utc.localize(utc_time)

    def __init__(self, link, attributes):
        self._link = link
        self.__attributes = attributes
        self._history = [(Property._current_time(), attributes)]

    def update(self, new_attributes):
        def dictdiff(d1, d2):                                              
            return dict(set(d2.items()) - set(d1.items()))
        attr_change = dictdiff(self.__attributes, new_attributes) 
        self.__attributes.update(attr_change)
        self._history.append((Property._current_time(), attr_change))

    def show_attributes(self):
        return self.__attributes

    def show_history(self):
        # how to show changes in time?
        return self._history


prop = Property(1234, {"Price":3000, "Active":"Yes"})
prop.update({"Price":2500, "Active":"Yes"})
prop.update({"Active":"No"})
prop.show_history()

然后输出:

Out[132]: 
[(datetime.datetime(2018, 10, 28, 10, 24, 19, 712385, tzinfo=<UTC>),
  {'Price': 2500, 'Active': 'No'}),
 (datetime.datetime(2018, 10, 28, 10, 24, 19, 712385, tzinfo=<UTC>),
  {'Price': 2500}),
 (datetime.datetime(2018, 10, 28, 10, 24, 19, 712385, tzinfo=<UTC>),
  {'Active': 'No'})]

历史上的第一项实际上应该是:

(datetime.datetime(2018, 10, 28, 10, 24, 19, 712385, tzinfo=<UTC>),
  {"Price":3000, "Active":"Yes"})

我尝试了this,但没有成功。似乎 init 函数在更新属性时正在更新初始化历史记录,同时在历史记录中我首先想查看第一次初始化的属性。

【问题讨论】:

标签: python class dictionary updates


【解决方案1】:

问题是你正在用这段代码修改历史中的字典:

self.__attributes.update(attr_change)

你基本上是这样做的:

>>> attributes = {}
>>> history = [attributes]
>>> attributes.update(foo=3)
>>> history
[{'foo': 3}]

这很容易通过在历史记录中存储字典的副本来解决:

self._history = [(Property._current_time(), attributes.copy())]

另见How to copy a dictionary and only edit the copy

【讨论】:

    【解决方案2】:

    您希望第一个历史条目是attributes副本

    self._history = [(Property._current_time(), dict(attributes))]
    

    正如你现在的代码,第一个历史条目references current 属性字典。

    【讨论】:

      猜你喜欢
      • 2016-12-06
      • 2021-07-27
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      • 2013-10-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多