简体   繁体   中英

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). 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?

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?

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.

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__ .

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:

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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