I am trying to make a simple compression program in Python, but am receiving this error
with open("admin.dll", "r").read() as text:
AttributeError: __exit__
Why am I getting this error? This is my full code
import zlib, sys, time, base64
with open("admin.txt", "r").read() as file:
print("Uncompressed: " + str(sys.getsizeof(file)))
compressed = zlib.compress(file, 9)
print("Compressed: ", end="")
print(sys.getsizeof(compressed))
You are asking Python to treat the result of the expression open("admin.dll", "r").read() (a string) as a context manager. Context managers are expected to have a __exit__ method, but strings don't have those methods.
You'd normally pass in the file object:
with open("admin.dll", "r") as fileobj:
text = fileobj.read()
File objects do have the required context manager methods.
Note that you have other errors too; sys.getsizeof produces the memory size of a Python object, not the size of a file. You could use os.stat() for that, or seek to the end of the file and use fileobj.tell() to get a size. To get the size of the compressed result, use len().
I believe you should open the file. Appoint a variable to it. In your case file.
Then on the next line you can read the file by calling f.read()
Related
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 am having a great time trying to figure out why there doesn't need to be a closing attribute for this few lines of code I wrote:
from sys import argv
from os.path import exists
script, from_file, to_file = argv
file_content = open(from_file).read()
new_file = open(to_file, 'w').write(file_content)
new_file.close()
file_content.close()
I read some things and other people's posts about this, but their scripts were a lot more complicated than what I'm currently learning, so I couldn't figure out why.
I am doing Learning Python the Hard Way and would appreciate any help.
file_content is a string variable, which contains contents of the file -- it has no relation to the file. The file descriptor you open with open(from_file) will be closed automatically: file sessions are closed after the file-objects exit the scope (in this case, immediately after .read()).
open(...) returns a reference to a file object, calling read on that reads the file returning a string object, calling write writes to it returning None, neither of which have a close attribute.
>>> help(open)
Help on built-in function open in module __builtin__:
open(...)
open(name[, mode[, buffering]]) -> file object
Open a file using the file() type, returns a file object. This is the
preferred way to open a file.
>>> a = open('a', 'w')
>>> help(a.read)
read(...)
read([size]) -> read at most size bytes, returned as a string.
If the size argument is negative or omitted, read until EOF is reached.
Notice that when in non-blocking mode, less data than what was requested
may be returned, even if no size parameter was given.
>>> help(a.write)
Help on built-in function write:
write(...)
write(str) -> None. Write string str to file.
Note that due to buffering, flush() or close() may be needed before
the file on disk reflects the data written.
Theres a couple ways of remedying this:
>>> file = open(from_file)
>>> content = file.read()
>>> file.close()
or with python >= 2.5
>>> with open(from_file) as f:
... content = f.read()
The with will make sure the file is closed.
When you do file_content = open(from_file).read(), you set file_content to the contents of the file (as read by read). You can't close this string. You need to save the file object separately from its contents, something like:
theFile = open(from_file)
file_content = theFile.read()
# do whatever you need to do
theFile.close()
You have a similar problem with new_file. You should separate the open(to_file) call from the write.
if __name__ == '__main__':
filename = open('sevi.txt', 'wb')
content = filename.write("Cats are smarter than dogs")
for line in content.read():
match = re.findall('[A-Z]+', line)
print match
filename.close()
I am new to python. I am just opening a file and writing some text into it. Later reading the content find all the characters in it by using regular expression. but I am getting the error as 'NoneType' object has no attribute 'read'. if I use readlines also, I am getting the error.
The file.write() method returns None in Python 2 (in Python 3 it returns the number of bytes written, for a binary file).
If you want to both write and read with the same file you'll need to open that file in w+ mode, and seek back to put the file position back to the start:
with open('sevi.txt', 'w+b') as fileobj:
fileobj.write("Cats are smarter than dogs")
fileobj.seek(0) # move back to the start
for line in fileobj:
match = re.findall('[A-Z]+', line)
print match
Note that looping over the file object can be done directly, producing individual lines.
I made two other changes: I renamed your variable to fileobj; you have a file object, not just the name of the file here. And I used the file object as a context manager, so that it is closed automatically even if any errors occur in the block.
filename.write("Cats are smarter than dogs") is the function that returns None type like every function in Python if it's not specified otherwise with a return statement. So the value of the variable content is None and You are trying to read from that. Try filename.read() instead.
import re
ofile = open('sevi.txt', 'r+')
ofile.write("Cats are smarter than dogs")
ofile.seek(0)
data = ofile.read()
upper = re.findall(r'[A-Z]', data)
print upper
lower = re.findall(r'[a-z]', data)
print lower
ofile.close()
I am having a great time trying to figure out why there doesn't need to be a closing attribute for this few lines of code I wrote:
from sys import argv
from os.path import exists
script, from_file, to_file = argv
file_content = open(from_file).read()
new_file = open(to_file, 'w').write(file_content)
new_file.close()
file_content.close()
I read some things and other people's posts about this, but their scripts were a lot more complicated than what I'm currently learning, so I couldn't figure out why.
I am doing Learning Python the Hard Way and would appreciate any help.
file_content is a string variable, which contains contents of the file -- it has no relation to the file. The file descriptor you open with open(from_file) will be closed automatically: file sessions are closed after the file-objects exit the scope (in this case, immediately after .read()).
open(...) returns a reference to a file object, calling read on that reads the file returning a string object, calling write writes to it returning None, neither of which have a close attribute.
>>> help(open)
Help on built-in function open in module __builtin__:
open(...)
open(name[, mode[, buffering]]) -> file object
Open a file using the file() type, returns a file object. This is the
preferred way to open a file.
>>> a = open('a', 'w')
>>> help(a.read)
read(...)
read([size]) -> read at most size bytes, returned as a string.
If the size argument is negative or omitted, read until EOF is reached.
Notice that when in non-blocking mode, less data than what was requested
may be returned, even if no size parameter was given.
>>> help(a.write)
Help on built-in function write:
write(...)
write(str) -> None. Write string str to file.
Note that due to buffering, flush() or close() may be needed before
the file on disk reflects the data written.
Theres a couple ways of remedying this:
>>> file = open(from_file)
>>> content = file.read()
>>> file.close()
or with python >= 2.5
>>> with open(from_file) as f:
... content = f.read()
The with will make sure the file is closed.
When you do file_content = open(from_file).read(), you set file_content to the contents of the file (as read by read). You can't close this string. You need to save the file object separately from its contents, something like:
theFile = open(from_file)
file_content = theFile.read()
# do whatever you need to do
theFile.close()
You have a similar problem with new_file. You should separate the open(to_file) call from the write.
I'm using the latest GAE default python environment. Both of these give expected results:
isTrue = os.path.exists(path)
numberGreaterThanZero = os.path.getsize(path)
But this:
myStrLen = len(open(path))
Gives this error:
TypeError: object of type 'FakeFile' has no len()
There are no results for that error in Google. Not being able to open files is a real bummer. What am I doing wrong? Why does Python/GAE think my file is fake?
The open function returns an open file, not a string. Open files have no len.
You need to actually read the string from the file, for example with the read method.
contents = open(path).read()
myStrLen = len(contents)
If you don't need the contents, you can also get the file size with os.stat.
myStrLen = os.stat('/tmp/x.py').st_size
FakeFile is just GAE's sandboxed implementation of file.