16

Possible Duplicate:
Python - When to use file vs open

From the official python documentation,

http://docs.python.org/library/functions.html#file

When opening a file, it’s preferable to use open() instead of invoking this constructor directly

But it doesn't give a reason.

Community
  • 1
  • 1
balki
  • 26,394
  • 30
  • 105
  • 151
  • 4
    For starters, it is gone in Python 3. Though that's a consequence and reinforcement, not a reason. –  Aug 13 '12 at 21:23
  • @delnan What type does `open` return in py3 then? – Marcin Aug 13 '12 at 21:24
  • 1
    I'm not positive on this, so I won't make an answer for it, but it may have to do with how Python handles the "with" keyword. I'm unsure if you can use "with" with a constructor. – LunchMarble Aug 13 '12 at 21:24
  • 2
    @Marcin One of the types in `io`. –  Aug 13 '12 at 21:25
  • <_io.TextIOWrapper name='/tmp/a' mode='w+' encoding='UTF-8'> – drjd Aug 13 '12 at 21:25
  • @ВидулПетров Nope, this question already presupposes `open` is preferable and asks *why*, which that question does not answer. –  Aug 13 '12 at 21:28
  • 5
    @StormKiernan: both `file` and `open` work with the `with`-statement. Anything that defines correct `__enter__()`, `__exit__()` methods would work. – jfs Aug 13 '12 at 21:29
  • @drjd Not always. With a `rb` "mode", I get a `BufferedReader`. Chances are there are even more variations. –  Aug 13 '12 at 21:29
  • @delnan thanks for that, but you can be sure, that the object has a read method if you open it in read mode and a write method if you open it in write mode – drjd Aug 13 '12 at 21:31
  • 1
    History investigation waypoint: http://hg.python.org/cpython/file/4dd52ba52de8/Doc/lib/libfuncs.tex – Martijn Pieters Aug 13 '12 at 21:45
  • 'Fred' is Fred Drake, and the 'discussion' would almost certainly have been in email, probably on the python dev list. – Martijn Pieters Aug 13 '12 at 21:50
  • 1
    and from 2.2 docs "The file() constructor is new in Python 2.2. The previous spelling, open(), is retained for compatibility, and is an alias for file(). " so I would guess just a design error in adding file() – mmmmmm Aug 13 '12 at 21:58

1 Answers1

18

The Zen of Python:

There should be one-- and preferably only one --obvious way to do it.

So either file or open should go.

>>> type(file)
<type 'type'>
>>> type(open)
<type 'builtin_function_or_method'>

open is a function that can return anything. file() returns only file objects.

Though it seems open returns only file objects on Python 2. And before Python 2.5 file and open are the same object.

As @gnibbler suggested in the comments the original reason for the existence of file might be to use it as the name for base classes.

Also, file() in principle could return other types as for example int() did on earlier Python versions:

>>> type(int(2**64)) is long
True
>>> type(int()) is int
True
>>> int is long
False

This answer is very similar to @Ryan's answer.

In addition BDFL said:

"The file class is new in Python 2.2. It represents the type (class) of objects returned by the built-in open() function. Its constructor is an alias for open(), but for future and backwards compatibility, open() remains preferred." (emphasis mine)

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • Does it actually do return anything but `file` objects? –  Aug 13 '12 at 21:32
  • 1
    @delnan: as far as I know it returns `file` objects on Python 2. It returns objects of different types on Python 3. – jfs Aug 13 '12 at 21:35
  • Originally `file` was and alias of `open` because it seemed awkward to subclass `open` – John La Rooy Aug 13 '12 at 21:37
  • @gnibbler: It was before Python 2.5 – jfs Aug 13 '12 at 21:40
  • @J.F.Sebastian Seeing as `file` is gone, this may be the reason for removal in Python 3 (though research is warranted). It's not really a reason for avoiding it in Python 2, as the docs seem to actively encourage that `isinstance(open(), file)`. –  Aug 13 '12 at 21:43
  • 7
    My own idiosyncratic view: `for file in files:` is so natural and Pythonic that making it clobber a builtin always seemed like a misstep. I've been using `for file in files:` anyway, just because I like the look of it. – DSM Aug 13 '12 at 22:09