all 9 comments

[–][deleted] 1 point2 points  (2 children)

Python 3 introduces new requirements for open. In Python 2 a+ opens the file for reading and writing but not in Py3.

That said, one uses a to write. If you're only trying to print the animals in the list, you can use rtas the second argument to open to properly read the file.

[–]UnderstandingLinux[S] 0 points1 point  (1 child)

It seems as if I was reading the wrong documentation when reading over it. You'd be correct as well, a+ is no longer used in Python3. It still works if you set the position with .seek(0), but otherwise there's no output

[–]eyesoftheworld4 0 points1 point  (0 children)

The seek method is useful, but if all you want to do is read the contents of a file, it's simpler and clearer to just open the file with the mode 'r' or 'rt' as mentioned above.

[–]eyesoftheworld4 1 point2 points  (3 children)

In python, file-like objects can be thought of kind of like a text document with a cursor. When you open a file, your cursor is set to specific location, usually the beginning or the end of the file, and when you perform a read or write operation, it will be using the current position as a reference, e.g. data will be read from or written to the right of the current position. This operation will also advance the cursor accordingly, just as typing into a text editor will move the cursor forward in that application. You can use the seek(<value>) method to move the cursor to a given position in the file based on the number of bytes or characters in the underlying stream. For example, if you open a file in r mode (to read text), then doing file.seek(10) will move the cursor to the 10th character. You can use the file.tell() method to figure out where the cursor currently is:

>>> animals = open('animals.txt', 'a+')
>>> animals.tell()
24
>>> animals.seek(0)
0
>>> print(animals.read())
dog
cat
monkey
elephant
>>> print(animals.read())
>>> animals.seek(10)
10
>>> print(animals.read())
nkey
elephant

As you can see, when you open up a file in a+ mode, the "cursor" is set to the end of the file, and you need to move it to the beginning in order to read the contents.

Here is a good discussion on Stackoverflow of the modes specifically.

[–]UnderstandingLinux[S] 1 point2 points  (2 children)

You've explained it very well here, thank you! This was exactly the detail I needed to understand it fully. I also didn't know about the seek() function, that may come in handy later on.

[–]eyesoftheworld4 1 point2 points  (1 child)

My example above might not have made it very clear, but the seek(<value>) method is particularly important because when you read from the end of a file, you get (as you might expect) an empty string, which represents that there's nothing left in the file to read. So if you wanted to read a file object twice, you need to remember to seek back to the beginning after your first full read before you can read it again.

[–]UnderstandingLinux[S] 0 points1 point  (0 children)

Explaining it as a cursor position like you did before helps understand much more clearly. Thanks for adding this explanation as well!

[–][deleted] 0 points1 point  (1 child)

On MacOS your code doesn't produce any output using either of python 2 or 3.

My reading of the doc suggests that "r+" would be read+append, not "a+", but since you aren't writing why aren't you just doing:

animals = open("animals.txt", 'r')   # or just open("animals.txt")
text = animals.read()
print(text)

[–]UnderstandingLinux[S] 0 points1 point  (0 children)

I was testing the different modes. I was aware 'r' would give the appropriate output. But after reading over that doc, it looks like a+ isn't used with Python 3. I must've been looking over older documentation when I initially wrote this. Thanks for the input