简体   繁体   English

如何覆盖现有的字典 Python 3

[英]How to overwrite an existing dictionary Python 3

Sorry if this is worded badly, I hope you can understand/edit my question to make it easier to understand.对不起,如果这措辞不好,我希望您能理解/编辑我的问题以使其更容易理解。

Ive been using python pickle to pickle/unpickle the state of the objects in a game (i do understand this is probably very storage/just generally inefficient and lazy but its only whilst im learning more python).我一直在使用 python pickle 来pickle/unpickle 游戏中对象的状态(我知道这可能是非常存储/只是通常效率低下和懒惰,但它只是在我学习更多 python 的时候)。 However I encounter errors when doing this with the classes for presenting information.但是,在使用用于呈现信息的类执行此操作时,我遇到了错误。

The issue at root I believe is that when I unpickle the save data to load, it overwrites the existing dictionaries but the object storage points change, so the information class is trying to detect a room that the player can no longer enter since the data was overwritten.我认为根本问题是,当我解开要加载的保存数据时,它会覆盖现有字典但对象存储点会发生变化,因此信息类试图检测玩家无法再进入的房间,因为数据是覆盖。

I've made a snippet to reproduce the issue I have:我制作了一个片段来重现我遇到的问题:

import pickle

class A(object):
  def __init__(self):
    pass

obj_dict = {
                      'a' : A(),
                      'b' : A()
                       ## etc.
                    }

d = obj_dict['a']

f = open('save', 'wb')
pickle.Pickler(f,2).dump(obj_dict)
f.close()

f = open('save', 'rb')
obj_dict = pickle.load(f)
f.close()

if d == obj_dict['a']:
  print('success')
else:
  print(str(d) + '\n' + str(obj_dict['a']))

I understand this is probably to be expected when rewriting variables like this, but is there a way around it?我知道在重写这样的变量时这可能是意料之中的,但是有没有办法解决它? Many thanks非常感谢

Is your issue that you want d == obj_dict['a'] to evaluate to true?您是否希望d == obj_dict['a']评估为真?

By default, the above == equality check will compare the references of the two objects.默认情况下,上面的==相等检查将比较两个对象的引用。 Ie does d and obj_dict['a'] point to the same chunk of memory?dobj_dict['a']指向同一块内存?

When you un-pickle your object, it will be created as a new object, in a new chunk of memory and thus your equality check will fail.当你 un-pickle 你的对象时,它将被创建为一个新对象,在一个新的内存块中,因此你的平等检查将失败。

You need to override how your equality check behaves to get the behavior you want.您需要覆盖平等检查的行为方式以获得所需的行为。 The methods you need to override are: __eq__ and __hash__ .您需要覆盖的方法是: __eq____hash__

In order to track your object through repeated pickling and un-pickling, you'll need to assign a unique id to the object on creation:为了通过重复酸洗和取消酸洗来跟踪您的对象,您需要在创建时为对象分配一个唯一的 id:

class A:
  def __init__(self):
    self.id = uuid.uuid4() # assign a unique, random id

Now you must override the methods mentioned above:现在你必须覆盖上面提到的方法:

def __eq__( self, other ):
  # is the other object also a class A and does it have the same id
  return isinstance( other, A ) and self.id == other.id

def __hash__( self ):
  return hash(self.id)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM