在未更改的实体上避免使用.put()的优雅方法

Bem*_*mmu 12 python google-app-engine

我在GAE上的Python编程中重现的模式是从数据存储中获取一些实体,然后可能根据各种条件更改该实体.最后,我需要将.put()实体返回到数据存储,以确保可以保存对其进行的任何更改.

然而,实际上通常没有进行任何更改,最终的.put()只是浪费金钱.如果真的发生变化,如何轻松确定我只放了一个实体?

代码可能看起来像

def handle_get_request():
    entity = Entity.get_by_key_name("foobar")

    if phase_of_moon() == "full":
       entity.werewolf = True
    if random.choice([True, False]):
       entity.lucky = True
    if some_complicated_condition:
       entity.answer = 42

    entity.put()
Run Code Online (Sandbox Code Playgroud)

如果任何条件改变了实体,我可以保持一个"已更改"的标志,但这似乎非常脆弱.如果我忘记将它设置在某个地方,那么更改将会丢失.

我最终使用了什么

def handle_get_request():
    entity = Entity.get_by_key_name("foobar")
    original_xml = entity.to_xml()

    if phase_of_moon() == "full":
       entity.werewolf = True
    if random.choice([True, False]):
       entity.lucky = True
    if some_complicated_condition:
       entity.answer = 42

    if entity.to_xml() != original_xml: entity.put()
Run Code Online (Sandbox Code Playgroud)

我不会称之为"优雅".优雅的是,如果对象最终自动保存自己,但我觉得这很简单,可读性足以做到现在.

Jos*_*Fox 4

为什么不检查结果是否等于( ==)原来的结果,然后决定是否保存它。这取决于正确实现的__eq__,但默认情况下基于 的逐字段比较__dict__应该可以做到这一点。

  def __eq__(self, other) : 
        return self.__dict__ == other.__dict__
Run Code Online (Sandbox Code Playgroud)

(如果执行此操作,请确保其他丰富的比较和哈希运算符正常工作。请参阅此处。)