I am trying to create a pickle file.
I have used the following piece of code to do it:
def pickler(input_nparray):
with open('/Users/username/Desktop/pklfilename.pkl', 'wb+') as f:
pickle.dump(input_nparray, f)
This method works perfectly. What this does is it takes in the numpy array and stores the contents into the pklfilename.pkl.
But the problem here is I have to specify the filename. This I tried to do in the following way, but failed.
def pickler(input_nparray, pklfilename):
with open('/Users/swaghccc/Desktop/' + pklfilename, 'wb+') as f:
pickle.dump(input_nparray, f)
pickler(input_nparray, 'file1.pkl')
Can someone tell me the correct alternative?
The username differs between the first and second example. Change it to username and use the filename pklfilename.pkl and see if you end up with a file in the second example.
Another tip is to save the filename in a variable a print it to try to figure out what goes on.
Related
I have a project in that I initialize two log files in a class using 'setup_image_and_model_folders' as follows.
results_header = ['Image count','File path','Wafer','Die','Name']
def setup_image_and_model_folders(self):
self.open_results_log()
def open_results_log(self):
# creating log file to write all inspected files
log_file = open(self.logs_csv,'a')
self.log_writer = csv.writer(log_file)
#creating results log file which only includes metal detected
csv_file = open(self.results_csv,'w')
self.csv_writer = csv.writer(csv_file)
if not os.path.exists(self.results_csv):
self.csv_writer.writerow(results_header)
def write_results(self, data):
self.csv_writer.writerow(data)
def write_logs(self, log):
self.log_writer.writerow(log)
It creates the CSV files at two locations specified in the path. However, 'results_csv' is empty although I write the header.
Also no matter how many times I call 'write_results' and 'write_logs', nothing gets written into the files.
This is the first time I am using the class-based approach to update files. If I write the same thing in one function, it works fine.
What is wrong here?
Maybe you forgot to close the file.
Try to store the csv_file as self.csv_file and run close(your_class_instance.csv_file) after writing.
If this solves the issue, try to rewrite your code so that it uses a context manager, via:
with open(path_to_file, "w") as file:
... write to file ...
then file will be closed automatically.
I'm a total beginner in Python. I've been trying to shorten the #1 version (which works fine) to a cleaner code and I thought I could just squeeze it into a one-liner. Why doesn't the #2 work?
I'm getting the "NoneType" object has no attribute 'seek' when I try to run it.
from sys import argv
script, filename = argv
# 1
open_file = open(filename, 'w+')
open_file.write("Hello world!")
open_file.seek(0)
print open_file.read()
# 2
open_file = open(filename, 'w+').write("Hello world!").seek(0).read()
print open_file
I have tried numerous ways but I still can't get it to work.
Thanks a lot!
From the documentation:
write(b):
Write the given bytes-like object, b, to the underlying raw stream, and return the number of bytes written
So, it returns the number of bytes written, not a file object, so you cannot chain another call after the write(). Note you also cannot chain seek() as that returns an offset into the file.
The reason why a one-liner is not working, is because .write() does not return back the original file descriptor. Instead, write() returns the number of characters/bytes (depending on the opened file mode) that have been written.
Unfortunatelly I don't think there's a way to do what you want in one go, that would not sacrifice readability. What you could do is wrap your code into a function, or write your own file-like object that would immediatelly seek after write.
For writing,
with open(filename, 'w+') as f: f.write("Hello world!")
and to print content
with open(filename, 'r+') as f: print(f.read())
works for me! Nonetype error is because of no return type as pointed out by others.
You are getting NoneType because file.write function return None. Or in this case int (How many bytes it has write on the file)
You must close the file before you open again it. open_file.close()
I'm not sure how to word my question exactly, and I have seen some similar questions asked but not exactly what I'm trying to do. If there already is a solution please direct me to it.
Here is what I'm trying to do:
At my work, we have a few pkgs we've built to handle various data types. One I am working with is reading in a csv file into a std_io object (std_io is our all-purpose object class that reads in any type of data file).
I am trying to connect this to another pkg I am writing, so I can make an object in the new pkg, and covert it to a std_io object.
The problem is, the std_io object is meant to read an actual file, not take in an object. To get around this, I can basically write my data to temp.csv file then read it into a std_io object.
I am wondering if there is a way to eliminate this step of writing the temp.csv file.
Here is my code:
x #my object
df = x.to_df() #object class method to convert to a pandas dataframe
df.to_csv('temp.csv') #write data to a csv file
std_io_obj = std_read('temp.csv') #read csv file into a std_io object
Is there a way to basically pass what the output of writing the csv file would be directly into std_read? Does this make sense?
The only reason I want to do this is to avoid having to code additional functionality into either of the pkgs to directly accept an object as input.
Hope this was clear, and thanks to anyone who contributes.
For those interested, or who may have this same kind of issue/objective, here's what I did to solve this problem.
I basically just created a temporary named file, linked a .csv filename to this temp file, then passed it into my std_read function which requires a csv filename as an input.
This basically tricks the function into thinking it's taking the name of a real file as an input, and it just opens it as usual and uses csvreader to parse it up.
This is the code:
import tempfile
import os
x #my object I want to convert to a std_io object
text = x.to_df().to_csv() #object class method to convert to a pandas dataframe then generate the 'text' of a csv file
filename = 'temp.csv'
with tempfile.NamedTemporaryFile(dir = os.path.dirname('.')) as f:
f.write(text.encode())
os.link(f.name, filename)
stdio_obj = std_read(filename)
os.unlink(filename)
del f
FYI - the std_read function essentially just opens the file the usual way, and passes it into csvreader:
with open(filename, 'r') as f:
rdr = csv.reader(f)
I am trying to make a file with a function in python, but I have no idea how. This is what I have, and what I need.
def file_maker():
file_number = input("What number player are you? ")
#Insert however you make a file in code, naming it ('inventory.' + filenumber + '.txt')
I only need to know how I would initiate the file-making process. I tried googling it, but the only thing that comes up is how to access a function within a different file. I am an amateur programmer, any and all suggestions are welcome. Thanks for your time.
def file_maker():
file_number = input("What number player are you? ")
with open("inventory.%s.txt" % file_number, "w") as f:
# Do whatever you need with the file using the 'f' to refer to the file object
pass # in case you don't want to do anything with the file, but just create it
Read more regarding open function here: Open function
FYI, this will overwrite the file if it already exists.
To create a file, just open in it write mode.
file_handle=open ('inventory.' + filenumber + '.txt', "w")
file_handle is now an object that you can use various methods on to add content to the file. Read the documentation here.
Make sure you close the file when you are done with it using file_handle.close()
Note: Although this method works, it is usually considered better practice to use with, as shown in the other answer. It uses less code and automatically closes the file when done.
I am trying to write a script that opens files based on dictionary values. For each key/value it opens a file based on that value's name and assigns that file to the name of the value (I think it's going wrong here). So far it opens the files for me, with the right names, so that works. However, I think the name I assign the open(file) function to is wrong, since the rest of my function does not open the files anymore, and I can't close them.
Example of my script:
filelist=[]
codeconv={"agt":"r1p1d", "aga":"r2p1d"}
for value in codeconv.values():
value=open("c:\Biochemistry\Pythonscripts\Splittest\split"+value+".txt", 'w')
filelist.append(value)
"Here I do something with the files"
for f in filelist:
f.close()
So the problem is, how do I assign the open(file) function to the correct name? (Here r1p1d and r2p1d for example) And how do I later call those again?
The error I get now is:
AttributeError: 'str'object has no attribute 'close'
on the f.close() line.
EDIT: It now works as I want it to, using the following code: (I also included the 'here I do something' part now just for clarity)
result=open("C:\\Biochemistry\\Pythonscripts\\Illuminaresults.txt", "r")
filelist=[]
codeconv={"agt":"r1p1d", "aga":"r2p1d"}
opened_files={}
for key, value in codeconv.items():
filename="c:\Biochemistry\Pythonscripts\Splittest\split"+value+".txt"
file=open(filename, 'w')
opened_files.update({key: file})
for line in result:
if line[0]==">":
lastline=line
if line[0:3] in codeconv and len(line)==64:
f=opened_files[line[0:3]]
f.write(lastline+line)
else: continue
for f in opened_files.values():
f.close()
result.close()
I got another problem now though when I try to write the next part of my script, but that's probably something for another question, as it gives a Windowserror not related to this part. Thanks for the help all!
If i understand you well, you want to create some variable dynamically from the dictionary so that you can assign them to the opened files, is that it ???!!!!
I will suggest to do it using another dictionary like this:
codeconv={"agt":"r1p1d", "aga":"r2p1d"}
opened_files = {}
for key, value in codeconv.items():
file_name = "c:\Biochemistry\Pythonscripts\Splittest\split%s.txt" % value
file=open(file_name, 'w')
opened_files.update({key: file})
you can now access your opened files from the dictionary like this:
f = opened_files['agt']
f.read()
....
and for you latter code do it like this:
for f in opened_files.values():
f.close()
I'd caution against reusing "value" in that first loop, for clarity and future bugs that might be introduced there.
But, the code you posted actually works, so obviously there's something else going on that we can't diagnose here. What you need to do is inspect the contents of filelist before you try to close the file handles in it. That will probably point you towards the answer.
Perhaps you want to append tuples to filelist so the name is associated with the file object
codeconv={"agt":"r1p1d", "aga":"r2p1d"}
for value in codeconv.values():
f=open("c:\Biochemistry\Pythonscripts\Splittest\split"+value+".txt", 'w')
filelist.append((value, f))
"Here I do something with the files"
for name, f in filelist:
f.close()
I can't see a problem in your code, maybe it's not in the part pasted? (in filelist, or the snipped bit).
But anyway, I would rewrite it to avoid using the same variable, value, for two different things:
filelist = []
codeconv={"agt":"r1p1d", "aga":"r2p1d"}
for file_id in codeconv.values():
f = open("c:\Biochemistry\Pythonscripts\Splittest\split"+file_id+".txt", 'w')
filelist.append(f)
"Here I do something with the files"
for f in filelist:
if isinstance(f, str):
print "WARNING: Expected file handle, got string:", f
else:
f.close()
(I also added a bit of troubleshooting code)
The files are already open - your filelist object contains open file objects that you can iterate over (for example, with for line_of_text in filelist[0]:) or call other functions of (see dir(file) for other members).
You can defer opening the file by assigning a lambda and calling it later, for example:
for value in codeconv.values():
value2 = lambda: open(complete_filename)
filelist.append(value2)
my_file_object = filelist[0]()
You may prefer to store these in a dictionary:
for value in codeconv.itervalues():
filedict[value] = lambda: open(complete_filename)
my_file_object = filedict["r1p1d"]()
Or if you really want to create new variables (I strongly recommend not doing this, but since you asked):
for value in codeconv.itervalues():
globals()[value] = open(complete_filename)
# or
#globals()[value] = lambda: open(complete_filename)
# if you prefer
Finally, you close the files as you already are (substituting filedict.itervalues() for filelist if you use a dictionary instead).
(Obviously you need to replace complete_filename in the above examples with however you calculate the actual filename. I shouldn't need to say this, but I've been stung too often by leaving out these sorts of details.)
You're not assigning the function, you are assigning the return value. Which appearantly is a string in this case instead of a file object, which is a bit surprising. Are you doing anything with the filelist in the "here I do something" part?
[edit]
ok, sounds like you want a dict between key/fileobject (with example usage).
codeconv={"agt":"r1p1d", "aga":"r2p1d"}
filedict = {key, open("c:\Biochemistry\Pythonscripts\Splittest\split"+value+".txt", 'w')
for key, value in codeconv.iteritems()}
#Here I do something with the files
filedict["agt"].write("foo")
filedict["aga"].write("bar")
for f in filedict.values():
f.close()