0

What I have is 3 dictionaries dumping with pickle to 3 different files. I had originally just written a read and write function for each file so a total of 6 functions. So last night I tried to make it so I would only have to use 1 read function and 1 write function. I got the write function to work but the read function is not. I have been looking since last night for a solution to this problem and I am fed up so any help you can give I would appreciate. I am new to programming/python if you could not tell. Here is the code I'm using:

w = {} # would be past in as source

def writing(filename, source): 
    with open(filename, 'wb') as st:
        pickle.dump(source, st)

def reading(filename, source):
    with open(filename, 'rb') as st:
        source = pickle.loads(st.read())

reading('test.txt', w)

The error I got is:

Traceback (most recent call last):
  File "./database.py", line 303, in <module>
   pw.check_pwd(p)
  File "./database.py", line 47, in check_pwd
    if self.pwds[self.user] == hashlib.sha512(self.pwd + self.salt).hexdigest():
KeyError: 'Codex' this was the error I was getting sorry for the bad post
brandizzi
  • 26,083
  • 8
  • 103
  • 158
Radioactive Head
  • 1,519
  • 2
  • 11
  • 11
  • What "problem" are you seeing? This code is syntactically correct. You need to tell us the issue and what you expect to see – Paul Seeb Jun 26 '12 at 17:06
  • I am getting a key error when trying to read from the file and then it posts the line that is trying to read from the file I did try return as suggested below but still get the same thing. – Radioactive Head Jun 26 '12 at 17:14
  • Three people answered this question when there was not a single "problem" stated until 2 minutes ago... – Paul Seeb Jun 26 '12 at 17:18
  • @Nick can you show us the error message? Fill out your question with an actual issue rather than putting it in the comments. – Paul Seeb Jun 26 '12 at 17:19

4 Answers4

1

You need to return source in the second function:

def reading(filename, source):
    with open(filename, 'rb') as st:
        source = pickle.loads(st.read())
    return source

Otherwise Python will default to returning nothing (None).

Katriel
  • 120,462
  • 19
  • 136
  • 170
1

I do not know what problem you are trying, but I am very confident that you want the result of the unpickling in the global w variable, right? Well, you cannot do it this way: when you attribute a value to the source variable, you are updating only the local variable source but the variable w still points to the same value. Maybe this answer may help you to understand what is happening.

There are various solutions to it. One of my favorite ones is the @katrielatex one: return the value:

def reading(filename, source):
    with open(filename, 'rb') as st:
        source = pickle.loads(st.read())
    return source
w = reading(filename, w)

Actually, you do not even need the source parameter:

def reading(filename):
    with open(filename, 'rb') as st:
        source = pickle.loads(st.read())
        return source

w = reading(filename)

Another solution is to update the dictionary pointed by source. In this case, no return is needed:

def reading(filename, source):
    with open(filename, 'rb') as st:
        source.update(pickle.loads(st.read()))

reading(filename, w)

Also, you can make w a global variable inside the function (but it is the worst solution):

def reading(filename):
    global w
    with open(filename, 'rb') as st:
        w = pickle.loads(st.read())

reading(filename)
Community
  • 1
  • 1
brandizzi
  • 26,083
  • 8
  • 103
  • 158
  • @Nick it is great that it worked! However, I suggest you to take some time to understand why it worked and your solution did not. This is a very important aspect of working with Python (and most object-oriented languages, for that matter) Aside the link I gave above, you can see [this great answer](http://stackoverflow.com/a/986145/287976). – brandizzi Jun 26 '12 at 17:24
  • Yeah just read the update link and now feel.... it was right in front of my face. I actually read that doc last night – Radioactive Head Jun 26 '12 at 17:30
1

If you are sure you get back a dict, your reading() could as well be like

def reading(filename, source):
    with open(filename, 'rb') as st:
        tmp = pickle.loads(st.read())
    source.update(tmp)

but, to be honest, the return solution by katrielalex is better.

Community
  • 1
  • 1
glglgl
  • 89,107
  • 13
  • 149
  • 217
0

Reading function only needs a file name and it should return something:

def save(filename, data): 
    with open(filename, 'wb') as f:
        pickle.dump(data, f)

def load(filename):
    with open(filename, 'rb') as f:
        return pickle.load(f)

Example:

save('data.pickle', [a, b, c])
a, b, c = load('data.pickle')
jfs
  • 399,953
  • 195
  • 994
  • 1,670