Trouble saving data to a text file - python

when I try to write data to a file I get no errors but when I try to read it back nothing is in the file. What am I doing wrong?
test = open('/Users/MYUSER/Desktop/test.txt', 'r+')
test.write("RANDOME STRING\n")
test.read()
''

You need to move the file pointer to the start of the file using file.seek before calling .read(). When you write something to a file, the file pointer moves to the end of file, that's why calling .read() on the file object was returning an empty string.
Demo:
>>> test = open('abc1', 'r+')
>>> test.write('foo')
>>> test.read()
''
>>> test.seek(0)
>>> test.read()
'foo'

Related

Opening .txt file does not show content or traceback but something else

I tried running this code in python. I ensured:
The .txt file was in the same file as the code file and the file name was "random.txt" saved in .txt format
file = input ('Enter File:')
if len(file) < 1 : file = 'random.txt'
fhan = open(file)
print (fhan)
My command prompt returned me <_io.TextIOWrapper name='random.txt' mode='r' encoding='cp1252'> with no traceback. I don't know how to get the file to open and print the content
Open a file, and print the file content:
with open('./demo.txt', 'r') as file:
txt = file.read()
print(txt)
fhan is a file handle, so printing it simply prints the results of calling its repr method, which shows what you see. To read the entire file, you can call fhan.read().
It's also good practice to use a with statement to manage resources. For example, your code can be written as
file = input('Enter File:')
if not file: # check for empty string
file = 'random.txt'
with open(file, 'r') as fhan: # use the `with` statement
print(fhan.read())
The benefit of this syntax is that you'll never have to worry about forgetting to close the file handle.

How to make a program that replaces newlines in python file with a string [duplicate]

This question already has answers here:
Why doesn't calling a string method (such as .replace or .strip) modify (mutate) the string?
(3 answers)
Closed 3 years ago.
I am trying to display my python file in html and therefore I would like to replace every time the file jumps to a newline with < br> but the program I've written is not working.
I've looked on here and tried changing the code around a bit I have gotten different results but not the ones I need.
with open(path, "r+") as file:
contents = file.read()
contents.replace("\n", "<br>")
print(contents)
file.close()
I want to have the file display < br> every time I have a new line but instead the code dosen't change anything to the file.
Here is an example program that works:
path = "example"
contents = ""
with open(path, "r") as file:
contents = file.read()
new_contents = contents.replace("\n", "<br>")
with open(path, "w") as file:
file.write(new_contents)
Your program doesn't work because the replace method does not modify the original string; it returns a new string.
Also, you need to write the new string to the file; python won't do it automatically.
Hope this helps :)
P.S. a with statement automatically closes the file stream.
Your code reads from the file, saves the contents to a variable and replaces the newlines. But the result is not saved anywhere. And to write the result into a file you must open the file for writing.
with open(path, "r+") as file:
contents = file.read()
contents = contents.replace("\n", "<br>")
with open(path, "w+") as file:
contents = file.write(contents)
there are some issues in this code snippet.
contents.replace("\n", "<br>") will return a new object which replaced \n with <br>, so you can use html_contents = contents.replace("\n", "<br>") and print(html_contents)
when you use with the file descriptor will close after leave the indented block.
Try this:
import re
with open(path, "r") as f:
contents = f.read()
contents = re.sub("\n", "<br>", contents)
print(contents)
Borrowed from this post:
import tempfile
def modify_file(filename):
#Create temporary file read/write
t = tempfile.NamedTemporaryFile(mode="r+")
#Open input file read-only
i = open(filename, 'r')
#Copy input file to temporary file, modifying as we go
for line in i:
t.write(line.rstrip()+"\n")
i.close() #Close input file
t.seek(0) #Rewind temporary file to beginning
o = open(filename, "w") #Reopen input file writable
#Overwriting original file with temporary file contents
for line in t:
o.write(line)
t.close() #Close temporary file, will cause it to be deleted

How to remove a section from an ini file using Python ConfigParser?

I am attempting to remove a [section] from an ini file using Python's ConfigParser library.
>>> import os
>>> import ConfigParser
>>> os.system("cat a.ini")
[a]
b = c
0
>>> p = ConfigParser.SafeConfigParser()
>>> s = open('a.ini', 'r+')
>>> p.readfp(s)
>>> p.sections()
['a']
>>> p.remove_section('a')
True
>>> p.sections()
[]
>>> p.write(s)
>>> s.close()
>>> os.system("cat a.ini")
[a]
b = c
0
>>>
It appears that the remove_section() happens only in-memory and when asked to write back the results to the ini file, there is nothing to write.
Any ideas on how to remove a section from the ini file and persist it?
Is the mode that I'm using to open the file incorrect?
I tried with 'r+' & 'a+' and it didn't work. I cannot truncate the entire file since it may have other sections that shouldn't be deleted.
You need to open the file in write mode eventually. This will truncate it, but that is okay because when you write to it, the ConfigParser object will write all the sections that are still in the object.
What you should do is open the file for reading, read the config, close the file, then open the file again for writing and write it. Like this:
with open("test.ini", "r") as f:
p.readfp(f)
print(p.sections())
p.remove_section('a')
print(p.sections())
with open("test.ini", "w") as f:
p.write(f)
# this just verifies that [b] section is still there
with open("test.ini", "r") as f:
print(f.read())
You need to change file position using file.seek. Otherwise, p.write(s) writes the empty string (because the config is empty now after remove_section) at the end of the file.
And you need to call file.truncate so that content after current file position cleared.
p = ConfigParser.SafeConfigParser()
with open('a.ini', 'r+') as s:
p.readfp(s) # File position changed (it's at the end of the file)
p.remove_section('a')
s.seek(0) # <-- Change the file position to the beginning of the file
p.write(s)
s.truncate() # <-- Truncate remaining content after the written position.

str object has no attribute 'close'

Im analyzing a text for word frequency and I am getting this error message after it is done:
'str' object has no attribute 'close'
I've used the close() method before so I dont know what to do.
Here is the code:
def main():
text=open("catinhat.txt").read()
text=text.lower()
for ch in '!"$%&()*+,-./:;<=>=?#[\\]^_{|}~':
text=text.replace(ch,"")
words=text.split()
d={}
count=0
for w in words:
count+=1
d[w]=d.get(w,0)+1
d["#"]=count
print(d)
text.close()
main()
You didn't save a reference to the file handle. You opened the file, read its contents, and saved the resulting string. There's no file handle to close. The best way to avoid this is to use the with context manager:
def main():
with open("catinhat.txt") as f:
text=f.read()
...
This will close the file automatically after the with block ends, without an explicit f.close().
That is because your variable text has a type of string (as you are reading contests from a file).
Let me show you the exact example:
>>> t = open("test.txt").read()
#t contains now 'asdfasdfasdfEND' <- content of test.txt file
>>> type(t)
<class 'str'>
>>> t.close()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'close'
If you use an auxiliary variable for the open() function (which returns a _io.TextIOWrapper), you can close it:
>>> f = open("test.txt")
>>> t = f.read() # t contains the text from test.txt and f is still a _io.TextIOWrapper, which has a close() method
>>> type(f)
<class '_io.TextIOWrapper'>
>>> f.close() # therefore I can close it here
>>>
text=open("catinhat.txt").read()
text is a str since that is what .read() returns. It does not have a close method. A file object would have a close method, but you didn't assign the file you opened to a name thus you can no longer refer to it to close it.
I recommend using a with statement to manage the file:
with open("catinhat.txt") as f:
text = f.read()
...
The with statement will close the file whether the block finishes successfully or an exception is raised.

python: can't work out why len function() is behaving not as expected

i have been working on a python tutorial and have come across a problem which i simply cannot work out. google has not turned up anything specific and after a few hours away and much trial and error i still cannot work it out.
anyway, the below code is a simplified version of the tutorial. it works fine and prints out that my file is 17 bytes long:
from sys import argv
from os.path import exists
script, file1 = argv
file_open = open(file1)
file_read = file_open.read()
print "the file is %s bytes long" % len(file_read)
then the tutorial asks to merge lines 6 and 7 into a single line. if i do it like this it works:
from sys import argv
from os.path import exists
script, file1 = argv
file_read = open(file1).read()
print "the file is %s bytes long" % len(file_read)
but, if i do it like like this then i get an error message which says TypeError: object of type 'file' has no len():
from sys import argv
from os.path import exists
script, file1 = argv
file_read = open(file1, "r+")
print "the file is %s bytes long" % len(file_read)
my problem is i cannot work out why that error message is occurring when i am adding the "r+" to make sure the open file is read. ( although, is it true that read is default anyway so maybe even adding the r+ is unnecessary )
any help would be much appreciated. many thanks :)
I think you forgot the .read() in:
file_read = open(file1, "r+")
so file_read is a file object. Try with:
file_read = open(file1, "r+").read()
and it will return a string as expected.
Regardless of whether you open it in r mode, r+ mode, or any other mode, opening a file with the open built-in returns a file object:
>>> open('test.txt', 'r+')
<open file 'test.txt', mode 'r+' at 0x013D9910>
>>> type(open('test.txt', 'r+'))
<type 'file'>
>>>
Moreover, you cannot use the len built-in on this object:
>>> len(open('test.txt', 'r+'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'file' has no len()
>>>
This is because, technically, a file object has no length. It is just a pointer to a certain file.
As you noted, the way to fix the problem is to first invoke the file object's read method. Doing so will return the file's contents as a string, which you can then use len on:
>>> open('test.txt', 'r+').read()
'hello world'
>>> len(open('test.txt', 'r+').read())
11
>>>
In the second example you are trying to find the length of the file pointer, which is not possible. SO add:
file_read.read()
instead of just file_read
When using len, it only accepts objects with a certain type if you're passing in an object with <type 'file'> it will throw an exception.
>>> f = open('/some/file/path', 'r+')
>>> type(f)
<type 'file'>
>>>
>>> type(f.read()) # the read method returns an object with type 'str'
<type 'str'>
Here f.read() returns a str object.

Categories