So this is my code, I would like to save the value 'test' to the file so that it can be called to be used when the program is reopened.
import pickle
test = 0
def Save():
with open('objs.pickle', 'wb') as f:
pickle.dump(test, f)
def Load():
with open('objs.pickle', 'rb') as f:
test = pickle.load(f)
The problem with this code is that when I reopen the program and run in and then type in Load(), it says that 'test' is still equal to 0. (Missing somehting obvious probably)
And so my question is, how could I fix the problem issued in italics?
The global variable test has nothing to do with test inside the function Load(). Change your function to:
def Load():
with open('objs.pickle', 'rb') as f:
return pickle.load(f)
Now this function returns the value it reads from the pickle file.
Call it like this:
print(Load())
Side note: By convention functions names are all lowercase in Python. So the function name should be actually load().
EDIT
The whole program in a better style:
import pickle
def save(file_name, obj):
with open(file_name, 'wb') as fobj:
pickle.dump(obj, fobj)
def load(file_name):
with open(file_name, 'rb') as fobj:
return pickle.load(fobj)
def main():
test = 0
file_name = 'objs.pickle'
save(file_name, test)
print(load(file_name))
if __name__ == '__main__':
main()
Related
I have 2 pickled files on the computer and I want to load it to my script. Would this code I wrote work in python?
import sys
import pickle
filename1 = sys.argv(1)
filename2 = sys.argv(2)
def read_file(filename1,filename2):
with open(filename1, 'rb') as file1:
file1=pickle.load()
with open(filename1, 'rb') as file2:
file2=pickle.load()
return file1
return file2
sys.exit()
As mentioned here:
1 # Load the dictionary back from the pickle file.
2 import pickle
3
4 favorite_color = pickle.load( open( "save.p", "rb" ) )
5 # favorite_color is now { "lion": "yellow", "kitty": "red" }
So in your case you can do:
def read_file(filename1,filename2):
with open(filename1, 'rb') as file1:
f1=pickle.load(file1)
with open(filename1, 'rb') as file2:
f2=pickle.load(file2)
return f1,f2
There are a few things that don't quite work here:
Your second with-clause is not inside of your function, neither are your returns
A function can only return once. When python reaches the first return inside a function, it exits that function. But you can return multiple things at once, e.g. with return file1, file2
Your pickle-loading is the other way around. Like this, you redefine your file1 and file2 - variables with whatever your call of pickle.load() (notice that it didn't get any arguments) would give you -- what you want is to pass the file you opened to pickle.load and then save the output of that to a new variable
You never actually called your read_file function
your indentation seems to be off
sys.argv is a list, you can't call it (Round braces, like sys.argv(1)) but you can index it (square brackets sys.argv[1])
import sys
import pickle
def read_file(filename1,filename2):
with open(filename1, 'rb') as file1:
data1 = pickle.load(file1)
with open(filename1, 'rb') as file2:
data2 = pickle.load(file2)
return data1, data2
filename1 = sys.argv[1]
filename2 = sys.argv[2]
your_data = read_file(filename1, filename2)
print(your_data) # Now you use your data, i used print as an example
sys.exit() # You usually only write that if you specifically need to
Further suggestion:
You don't necessarily have to make one function to handle two files, you can also just make one function to handle one file and call it twice.
import pickle
def read_file(filename):
with open(filename, 'rb') as file1:
data = pickle.load(file1)
return data1
filename1 = sys.argv[1]
filename2 = sys.argv[2]
your_data = read_file(filename1), read_file(filename2)
print(your_data)
as said, I'd like to open a json file and make it into a list, in order to append new elements to it and then dump all back into the json file.
Here is my code(the commented part is what I previously tried):
class Carta:
def __init__(self,filename):
self.__filename = filename
self.__lista = []
# try:
# f = open(self.__filename,"r")
# except:
# f = open(self.__filename, "w")
# f.close()
# f = open(self.__filename, "r")
with open(self.__filename) as file:
self.__lista = json.load(file)
# read=json.load(f)
# for c in leggi:
# self.__lista.append(c)
# print(self.__lista)
# f.close()
def add(self, c):
self.__lista.append(c)
def save(self):
f = open(self.__filename, "w")
for c in self.__lista:
f.write("%s\n" % str(c))
f.close()
It wouldn't work if you read from a JSON file, json list and then write custom string. Because next time you read the JSON file it's gonna fail.
So, during write/save you should make it json itself. Here's the code the explains how to do it.
import json
class Carta:
def __init__(self, filename):
self.__filename = filename
self.__lista = list()
self.read_from_json_file()
def read_from_json_file(self):
with open(self.__filename) as file:
self.__lista = json.load(file)
def write_to_json_file(self):
with open(self.__filename, 'w') as f:
json.dump(self.__lista, f)
def add(self, value):
self.__lista.append(value)
The reason you should use with open(filename, mode) as f: instead of f = open(filename) is because at the end of with block the file is automatically closed. Otherwise you've to call f.close() every time you open a file.
json.load - reads json data from file, converts to python data type/structure.
json.dump - read python data type/structure, converts it into string and stores it in the file (file handle) and saves the file.
Using pdb to trace errors
import json
import pdb
class Carta:
def __init__(self, filename):
self.__filename = filename
self.__lista = list()
self.read_from_json_file()
def read_from_json_file(self):
pdb.set_trace() # to pause execution and start debugger
# When paused,
# type n to continue to next line,
# type c to continue execution or to continue to the next loop
# type b <file_name>:<line_number> to add another break point, where <file_name> and <line_number> are place holders
# Example, b /home/username/hello.py:43, will add breakpoint at 43 line of hello.py in /home/username path
# type q to quit debugger and halt execution
with open(self.__filename) as file:
self.__lista = json.load(file)
def write_to_json_file(self):
with open(self.__filename, 'w') as f:
json.dump(self.__lista, f)
def add(self, value):
# Second breakpoint
pdb.set_trace()
self.__lista.append(value)
Or just run your file with
python -m pdb file.py and then add breakpoints. It will pause in the first line itself and return you a (pdb) console where you can add breakpoint.
import json
#read from file
with open("demofile.txt", "r") as f: x = f.read()
#parse
y = json.loads(x)
#edit
y["user"] = { "fname": "John", "lname": "Who"}
#save to file
with open("demofile.txt", "w") as f: f.write(json.dumps(y))
https://repl.it/#KrzysztofPecyna/PythonJsonExample
To read JSON from a file:
import json
with open('data.txt') as json_file:
data = json.load(json_file)
To add new data:
data['key'] = "value"
To write JSON to a file:
with open('data.txt', 'w') as outfile:
json.dump(data, outfile)
I have to create a save function and a load function that saves a dictionary in the format of:
123;Kalle;
123;Maria;
321;Anna;
321;Olle;
My dictionary is supposed to look like a phonebook, with the key being the name and the value is the phonenumber:
telebook = {"jacob":"8472923777", "nisse":"092563243"}
How can I write a function that saves my phonebook in the format mentioned? It should look like this:
8472923777;jacob;
This is my current code:
def save(lista, telebook):
import pickle
filename = lista[1]
f = open(filename, "w")
pickle.dump(telebook, f)
f.close()
print telebook
def load(lista, telebook):
import pickle
try:
filename = lista[1]
f = open(filename, "r")
telebook_1 = pickle.load( f )
telebook.clear()
telebook.update(telebook_1)
f.close()
print telebook
except:
print "This file doesn't exist"
EDIT:
My save function was easier than I thought, managed to solve it on my own. Not sure how to get the load function to work though.
book = raw_input("telebook> ").lower()
lista = book.split()
def save(lista, telebook):
filename = lista[1]
f = open(filename, "w")
for name, num in telebook.items():
f.write(num+";"+name+";"+"\n")
f.close()
print telebook
My load is the same as before but obviously I can't use that one anymore.
def save(telebok, filepath):
with open(filepath, 'w') as outfile:
for name,num in telebok.items():
outfile.write("{};{};\n".format(num, name))
And to get it back:
import csv
def load(filepath):
with open(filepath) as infile:
telebok = dict((v,k) for v,k,_ in csv.reader(infile, delimiter=';'))
return telebok
I'd like to figure out how I should use a class to read input from a file so that I can use that data in other classes. If I read input from a file into a list, should I pass that to another class that needs that to use that information?
Right now I have:
import sys
class FileReader:
"""Reads a file"""
def __init__(self):
input = ''
try:
with open(sys.argv[1], 'r') as inFile:
input = inFile.readline()
print(input)
except IndexError:
print("Error - Please specify an input file.")
sys.exit(2)
def main():
x = FileReader()
if __name__ == "__main__":
main()
I thought about making some kind of list to hold strings from the file, but I'm not sure whether that should be global or not.
If all you're trying to do is read the file line by line, something like the following would work just fine (exception handling omitted).
>>> path = '/path/to/file.txt'
>>> with open(path, 'r') as f:
... lines = [l for l in f]
You can then pass around lines as necessary.
I'm writing a module that uses FTPLib to fetch files. I want to find a way to pass a value(in addition to the block) to the callback. Essentially, my callback is
def handleDownload(block, fileToWrite):
fileToWrite.write(block)
And I need to call
ftp.retrbinary('RETR somefile', handleDownload)
And have it pass a file handle. Is there a way to do this?
You can close over the fileToWrite variable with a lambda:
fileToWrite = open("somefile", "wb")
ftp.retrbinary("RETR somefile", lambda block: handleDownload(block, fileToWrite))
This code worked for me.
class File:
cleared = False
def __init__(self, filepath):
self.filepath = filepath
def write(self,block):
if not File.cleared:
with open(f'{self.filepath}', 'wb') as f:
File.cleared = True
with open(f'{self.filepath}', 'ab') as f:
f.write(block)
else:
with open(f'{self.filepath}', 'ab') as f:
f.write(block)
ftp.retrbinary("RETR somefile", File(filepath).write)