views:

912

answers:

3

In python following statements do not work:

f = open("ftmp", "rw")
print >> f, "python"

I get the error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 9] Bad file descriptor

But with the following code it works:

g = open("ftmp", "r+")
print >> g, "python"

Looks like I need to revise the file modes, can you please tell me about the deep intricacies of the file opening modes.

+10  A: 

Better yet, let the documentation do it for you: http://docs.python.org/library/functions.html#open. Your issue in the question is that there is no "rw" mode... you probably want 'r+' as you wrote (or 'a+' if the file does not yet exist).

Jarret Hardie
+1: Reference the documentation.
S.Lott
A: 

Infact this is Okay but I found an "rw" mode on the socket in following code (for Python on S60) at lines 42 and 45:

http://www.mobilenin.com/mobilepythonbook/examples/057-btchat.html

Xolve
See http://docs.python.org/library/socket.html#module-socket. "Note Some behavior may be platform dependent, since calls are made to the operating system socket APIs." So it sounds like an S60-specific feature.
S.Lott
I'd also point out that r+ and a+ enable both read and write. Open a file with r+, and you can seek() around the file at will, overwriting or appending content. Is there a feature that you're expecting that the '+' series doesn't provide?
Jarret Hardie
+2  A: 

As an addition to @Jarret Hardie's answer here's how Python check file mode in the function fileio_init():

s = mode;
while (*s) {
 switch (*s++) {
 case 'r':
  if (rwa) {
  bad_mode:
   PyErr_SetString(PyExc_ValueError,
     "Must have exactly one of read/write/append mode");
   goto error;
  }
  rwa = 1;
  self->readable = 1;
  break;
 case 'w':
  if (rwa)
   goto bad_mode;
  rwa = 1;
  self->writable = 1;
  flags |= O_CREAT | O_TRUNC;
  break;
 case 'a':
  if (rwa)
   goto bad_mode;
  rwa = 1;
  self->writable = 1;
  flags |= O_CREAT;
  append = 1;
  break;
 case 'b':
  break;
 case '+':
  if (plus)
   goto bad_mode;
  self->readable = self->writable = 1;
  plus = 1;
  break;
 default:
  PyErr_Format(PyExc_ValueError,
        "invalid mode: %.200s", mode);
  goto error;
 }
}

if (!rwa)
 goto bad_mode;

That is: only "rwab+" characters are allowed; there must be exactly one of "rwa" in the mode.

J.F. Sebastian