1

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 :)

user2804628
  • 133
  • 1
  • 13
  • The last bit of code, `file_read` is a file-object. – tijko Feb 01 '14 at 16:32
  • hi, thanks for your reply. what i can't work out though is why this matters? i am complete beginner and i cannot see why i am getting the error if the file can be read? – user2804628 Feb 01 '14 at 16:54

4 Answers4

3

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.

fede1024
  • 3,099
  • 18
  • 23
2

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
>>>
  • hi, thank you for for taking the time to reply. i have been looking into what objects are and as far as i can tell everything is an object. i mean, why does adding the .read() work and why does just adding +r within the parameter break the code? what is python thinking to give me this error? thanks again. :) – user2804628 Feb 01 '14 at 16:55
  • @user2804628 - Well, as I said, using `open` returns a file object. At this point, you have not read-in the file's contents. Instead, you have just established a "connection" to the file. Invoking the `read` method however reads-in the file's contents and puts them in a string. You cannot use `len` on the file object because it has no length. It is just a pointer to the file. You can however use `len` on the string returned by the `read` method. –  Feb 01 '14 at 17:02
  • @user2804628 - And yes, [everything in Python is an object](http://stackoverflow.com/a/865963/2555451). :) –  Feb 01 '14 at 17:08
0

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

Aswin Murugesh
  • 10,831
  • 10
  • 40
  • 69
0

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.

tijko
  • 7,599
  • 11
  • 44
  • 64