Is there a way to stop Python rewriting files?
For example, when I run code once, it writes number "1" in text file. If I run same code tommorow, it won't erase that 1 from yesterday, it will add one more "1", so it should look like this:
1
1
My would look like this:
file = open("filename","w")
file.write(str(1) + "\n)
file.close()
If someone can tell me where is my mistake, please help me.
Thank you in advance !
If you read the docs for open, that second parameter that you're passing a "w" to is the mode:
mode is an optional string that specifies the mode in which the file is opened. It defaults to 'r' which means open for reading in text mode. Other common values are 'w' for writing (truncating the file if it already exists), 'x' for exclusive creation and 'a' for appending…
And then there's a handy chart of all of the mode characters, which reiterates the same information:
'w': open for writing, truncating the file first
...
'a': open for writing, appending to the end of the file if it exists
So, just use "a" instead of "w", and Python will add your new line to the end of the file, instead of truncating the file to nothing and then adding your new line to that now-empty file.
It's probably worth knowing that this is very closely based on the behavior of the fopen function from C and POSIX—which many other languages have also copied. So, in almost any language you run into, if there's a w mode for writing that overwrites the file, there's probably also an a mode for appending.
Related
I'm learning Python right now, and am trying to learn file handling using PyCharm CE on MacOS. While trying to open or create a new file, I get an error that goes something like this -
io.UnsupportedOperation: not readable
My code looks something like this:
import os
print (os.path.abspath(os.curdir))
fhand = open("file1.rtf", "w")
for line in fhand:
if line.startswith("from :") :
line = line.strip()
print(line)
How do I open a file and write something within it? And what is wrong with this code?
You opened the file in the wrong mode. This has nothing to do with PyCharm, but with your code :)
If you open a file in python (or most other programming languages), you have to specify, whether you want to read it or write it. You have more options than that, but let's keep it simple.
To do so, you use the second argument of the open() function, in your case "w", which stands for write.
If you want to read, change it to "r":
fhand = open("file1.rtf", "r")
If you want to read and write, you may use something like w+. To get an overview, you may find this diagram useful.
From the docs:
open() returns a file object, and is most commonly used with two arguments: open(filename, mode).
f = open('workfile', 'w')
The first argument is a string containing the filename. The second argument is another string containing a few characters describing the way in which the file will be used. mode can be 'r' when the file will only be read, 'w' for only writing (an existing file with the same name will be erased), and 'a' opens the file for appending; any data written to the file is automatically added to the end. 'r+' opens the file for both reading and writing. The mode argument is optional; 'r' will be assumed if it’s omitted.
I am starting a module that opens a file, reads it, does some stuff, and then appends to it. However, I am trying to see what is in the file first. Here is the start of the program:
def addSkill(company):
with open("companies.txt", "a+") as companies:
for line in companies:
print('ok')
print(line.rstrip('\n'))
companies.write(company + '\r\n')
companies.close()
Neither of the print functions are working. There is text in the document. And it appends to it as requested. Any suggestions?
Just open using 'r+' then save in memories everything that you need, then it will automatically writing at the end. because your file descriptor will be at the end.
Opening files in 'a' automatically put your file descriptor at the end, therefore, your can't see what was written before that.
e.g
def addSkill(company):
with open('companies.txt', 'r+') as fd:
list_of_companies = fd.readlines()
fd.write(company + '\n')
list_of_companies.append(company) # adding the last company to the full list.
print('\n'.join(list_of_companies)) # print each company with a '\n'.
Bonus: your close() method is useless using with, python will do that for you.
In any cases, when you are unsure about the option of a function, please RTFM: open()
'r' open for reading (default)
'w' open for writing, truncating the file first
'x' open for exclusive creation, failing if the file already exists
'a' open for writing, appending to the end of the file if it exists
'b' binary mode
't' text mode (default)
'+' open a disk file for updating (reading and writing)
'U' universal newlines mode (deprecated)
I am getting the following error when trying to output to a text file:
io.UnsupportedOperation: not writable.
My code:
def PostCodeStore(self):
#Opens the Postcode file in append mode
file = open("PostCode_File.txt", "r")
PostCodeValue= PostCodeVar.get()
#Writes the Postcode value to the file and adds a new line
file.write(PostCodeValue + "\n")
#Closes the file so it saves the value
file.close()
The reason is that you can't write to a file opened with 'r'. You must open with 'a'. From the documentation:
The first argument is a string containing the filename. The second argument is another string containing a few characters describing the way in which the file will be used. mode can be 'r' when the file will only be read, 'w' for only writing (an existing file with the same name will be erased), and 'a' opens the file for appending; any data written to the file is automatically added to the end. 'r+' opens the file for both reading and writing. The mode argument is optional; 'r' will be assumed if it’s omitted.
On Windows, 'b' appended to the mode opens the file in binary mode, so there are also modes like 'rb', 'wb', and 'r+b'. Python on Windows makes a distinction between text and binary files; the end-of-line characters in text files are automatically altered slightly when data is read or written. This behind-the-scenes modification to file data is fine for ASCII text files, but it’ll corrupt binary data like that in JPEG or EXE files. Be very careful to use binary mode when reading and writing such files. On Unix, it doesn’t hurt to append a 'b' to the mode, so you can use it platform-independently for all binary files.
This is a common issue, and (as seen in the docs), one that can cause some problems when writing cross-compatible programs, as Windows has a different set of permissions for binary files. You are likely not going to be working with binary files (maybe zipfiles), so I wouldn't worry about that too much. Just remember:
'w' # Writing
'r' # Reading (default)
'a' # Appending
'r+' # Read/Write
I believe I understand your problem correctly. That is, that your program wants to write many lines, one at a time (append). If you don't want to do that and just want a single entry in the file with a newline, you will want to use 'w'.
Also (and as a side note), Python class names generally start with a capital letter. That's why PostCodeValue shows up with different formatting. Conventionally, a variable like this should be named with small letters and underscores, such as post_code_value.
You're wrong
file = open("PostCode_File.txt", "r")#Opens the Postcode file in append mode
With r as mode, you open the file read-only, not append. That'd be a.
I know this is a simple question, but I am extremely stuck.
file=open("record.txt","w+")
record = file.read()
print("The record is "+str(record)+"!!")
main code...
file.write(str(reaction))
file.close()
I have got his code and I've got a number of 0.433534145355 in the file, but when I do the command of print the +str(record)+, it only comes up with The record is !! and the number is not there. What is wrong with this code. Is there a special code with decimal places, and I do not want to use int().
As it says here:
'w+' Open for reading and writing. The file is created if it does not
exist, otherwise it is truncated. The stream is positioned at
the beginning of the file.
so yes, your file is also opened for reading, but it is truncated (i.e. it is now zero bytes long, it's empty), leaving nothing left to read of what was there already.
Essentially, the w in 'w+' means the mode is orientated to writing, giving you the option to read as well (useful in those cases when you need to seek back and read what you have written. There will be nothing to read unless you write)
Instead you can use:
'r+' Open for reading and writing. The stream is positioned at the
beginning of the file.
In this case, the r in 'r+' signifies the mode is orientated to reading, giving you the option to seek and write where necessary (useful when data is present already, but might need to be changed)
If you want to read from a file, you have to open it for reading too (r).
I'm trying to input data from a csv and run that through a simple function and return it to the same CSV but appended onto the end of the row.
I'm having a hard time understanding the difference between the various modes(r, r+, a+, etc).
I've read the documentation but as a beginner am not understanding quite what they mean and which one is the right for me to be using in this case.
def appendCurrentTime():
with open("file.csv", "??") as myfile: #Opens File
reader = csv.reader(myfile)
for row in reader: #Runs through each row
myfile.write(current_time(row[1])) #appends the time, pulling in row[1] into current_time
**Also posting code for the first time, sorry if it doesn't come through clearly.
Looking at your code, the main problem is that the CSV file is not a "database", so you can't modify a row in the middle without corrupting the next row.
So, open the source file in "rb" mode and destination file in "wb" mode, and AFTER you processed the whole file - delete original and rename new file to the original name.
And, description for the cases you specified:
"r" - open text file for reading, starting from the beginning.
"r+" - open text file for reading and writing, starting from the beginning.
"a+" - create file if not exists; then open as a text file for reading and writing, starting from the end of file, plus you can only write to the end of the file.
In short, "R" means Read, "W" write, "+" - "and other way around", "B" - binary, absense of "B" means text. "A" differs from "W" in that "W" clears the file contents when you call open.
IMHO you should probably open files in binary mode most of the time, even if they are logically "text", to prevent unintended conversions of special characters (especially important with Unicode). So, I would recommend "wb" to "write new file", "rb" to "read existing" and "ab" to "append to existing file" e.g. a log file.
For even more information, read the documentation for the POSIX fopen function - Python tries to adhere to its semantics as much as possible, even on Windows systems.
Since it is a CSV file and implied text, the "rU" flag would be appropriate. The r flag means read and U is universal line terminator mode. This way it won't matter if the file is using Windows, Mac or Unix line terminators.
Also take a look into the Sniffer provided by the CSV library. It will automatically detect most dialects for you and can be passed into the reader function.
http://docs.python.org/2/library/csv.html#csv.Sniffer