1

I am trying to mimic a dict by using that as the base class. The objective is to meet these conditions:

If 2 arguments on the command line, set a key and value in the object's dictionary; if 1 argument on the command line, treat it as a key and show the value; if no arguments on the command line, show all keys and values.

Here is my code:

import pickle,os,sys class ConfigDict(dict): def __init__(self, filename): self._filename = filename if not os.path.exists(self._filename): with open(self._filename,"wb") as fh: pickle.dump({}, fh) with open(self._filename,"rb") as fh: self.update(pickle.load(fh)) def __setitem__(self, key, value): dict.__setitem__(self,key,value) with open(self._filename,"wb") as fh: pickle.dump(self, fh) def __getitem__(self,key): return dict.__getitem__(self,key) cd = ConfigDict('first.pickle') # if 2 arguments on the command line, # set a key and value in the object's dictionary if len(sys.argv) == 3: key, value = sys.argv[1], sys.argv[2] print('writing data: {0}, {1}'.format(key, value)) cd[key] = value # if 1 argument on the command line, treat it as a key and show the value elif len(sys.argv) == 2: print('reading a value') key = sys.argv[1] print('the value for {0} is {1}'.format(sys.argv[1], cd[key])) # if no arguments on the command line, show all keys and values else: print('keys/values:') for key in cd.keys(): print(' {0} = {1}'.format(key, cd[key])) 

I am able to write to the file, however, when i try to retrive the value for a given key, i hit the error (only the end of stack trace shown):

 with open(self._filename,"wb") as fh: AttributeError: 'ConfigDict' object has no attribute '_filename' 

But, i already set the _filename in __init__. What am i missing ?

1 Answer 1

1

Well, this is a tricky one - the problem seems to be with pickle.load(fh) and NOT with self.update( try this in two lines

... with open(self._filename,"rb") as fh: tmp = pickle.load(fh) self.update(tmp) ... 

this would fail at tmp =, so it's the object you're un-pickling that's failing. An easy fix would be to do pickle.dump(dict(self), fh), when serialising your things. Though this whole approach seems "forced" to me. Fully working version:

import pickle,os,sys class ConfigDict(dict): def __init__(self, filename): self._filename = filename if not os.path.exists(self._filename): with open(self._filename,"wb") as fh: pickle.dump({}, fh) with open(self._filename,"rb") as fh: self.update(pickle.load(fh)) def __setitem__(self, key, value): dict.__setitem__(self,key,value) with open(self._filename,"wb") as fh: pickle.dump(dict(self), fh) def __getitem__(self,key): return dict.__getitem__(self,key) cd = ConfigDict('first.pickle') # if 2 arguments on the command line, # set a key and value in the object's dictionary if len(sys.argv) == 3: key, value = sys.argv[1], sys.argv[2] print('writing data: {0}, {1}'.format(key, value)) cd[key] = value # if 1 argument on the command line, treat it as a key and show the value elif len(sys.argv) == 2: print('reading a value') key = sys.argv[1] print('the value for {0} is {1}'.format(sys.argv[1], cd[key])) # if no arguments on the command line, show all keys and values else: print('keys/values:') for key in cd.keys(): print(' {0} = {1}'.format(key, cd[key])) 
Sign up to request clarification or add additional context in comments.

1 Comment

what is the need to typecast the object as seen in your working code ? pickle.dump(dict(self), fh) works but pickle.dump(self, fh) does not. Please help understand

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.