44

I realised that the open() function I've been using was an alias to io.open() and that importing * from os would overshadow that.

What's the difference between opening files through the io module and os module?

Gio Borje
  • 20,314
  • 7
  • 36
  • 50
  • 3
    *From the [Python docs](http://docs.python.org/release/3.1.3/library/os.html#os.open):* This function [`os.open`] is intended for low-level I/O. For normal usage, use the built-in function `open()`, which returns a file object with `read()` and `wprite()` methods (and many more). To wrap a file descriptor in a file object, use `fdopen()`. – NullUserException Aug 28 '11 at 07:10
  • 2
    This question should be labelled as python3. In python2 `open()` and `io.open()` are different. – AnnanFay Nov 24 '17 at 00:46

7 Answers7

34

io.open() is the preferred, higher-level interface to file I/O. It wraps the OS-level file descriptor in an object that you can use to access the file in a Pythonic manner.

os.open() is just a wrapper for the lower-level POSIX syscall. It takes less symbolic (and more POSIX-y) arguments, and returns the file descriptor (a number) that represents the opened file. It does not return a file object; the returned value will not have read() or write() methods.

From the os.open() documentation:

This function is intended for low-level I/O. For normal usage, use the built-in function open(), which returns a “file object” with read() and write() methods (and many more).

cdhowie
  • 158,093
  • 24
  • 286
  • 300
  • 4
    Although I have to wonder, why would anyone choose Python for low-level I/O? – Karl Knechtel Aug 28 '11 at 10:14
  • 2
    Maybe Python is the language in which the coder is the most comfortable. Or maybe they are writing an addon for another Python program. – cdhowie Aug 28 '11 at 14:15
  • 3
    Why not? Low-level manipulation doesn't dictate in what language it should we expressed. – 0 _ Jul 01 '16 at 03:37
  • @IoannisFilippidis Because if you are going to use low-level interfaces, then why are you even using Python to begin with? Unless what you're doing can't be accomplished using higher-level interfaces, or the higher-level interfaces have severe performance issues, you should use the higher-level interfaces in the language you are using -- otherwise you should just use a different language altogether. – cdhowie Jul 01 '16 at 15:38
  • Python is more readable and flexible than writing in C, and there can be computations that benefit from accessing scientific packages written in Python. – 0 _ Jul 02 '16 at 01:31
  • @IoannisFilippidis That's my point. If you want the flexibility of Python, then you probably want to be using its high-level I/O interfaces anyway -- not doing so results in less portable, less readable, and less maintainable code. – cdhowie Jul 03 '16 at 03:48
  • 2
    My point is that you *do* want to write low-level code in Python, among *other*, high-level code, to which Python is more suited. – 0 _ Jul 03 '16 at 09:37
  • In any case, I would likely write it in Cython, so C, because flat is better than nested (PEP 20), and I've done so in the past, so the point here was more for the sake of discussion. – 0 _ Jul 03 '16 at 09:39
  • For an example of why you might want to use `os.open` see: https://stackoverflow.com/a/45368120/2705757 (setting file permission upon creation, without using `os.chmod`) – AXO Jan 11 '18 at 04:41
  • Using high or low-level interfaces is almost totally orthogonal to the language you're using. There's no reason low level interfaces must be used from C/C++ or so. High/low level interfaces are about level of detail you want to talk to system at , not about performance or static typing or anything of the short. Python, JS, Lisp, and even shell scripts can talk to low level interfaces just as well. – Hejazzman Jan 08 '20 at 11:03
  • 1
    @cdhowie that's a false dichotomy. You might want to use Python AND perform low level control of the system. It's also wrong that "not doing so results in less portable, less readable, and less maintainable code". Compared to what? Talking to the same low level APIs in C? No, it will be more portable and readable to talk to them from Python. If you mean "compared to using high level interfaces" that's a moot point, if what you need to do (business goal) involves low level interfaces. Low/High level APIs != Low/High level languages. – Hejazzman Jan 08 '20 at 11:05
7

Absolutely everything:

  • os.open() takes a filename as a string, the file mode as a bitwise mask of attributes, and an optional argument that describes the file permission bits, and returns a file descriptor as an integer.

  • io.open() takes a filename as a string or a file descriptor as an integer, the file mode as a string, and optional arguments that describe the file encoding, buffering used, how encoding errors and newlines are handled, and if the underlying FD is closed when the file is closed, and returns some descendant of io.IOBase.

Mathieu Rodic
  • 6,637
  • 2
  • 43
  • 49
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
5

To add to the existing answers:

I realised that the open() function I've been using was an alias to io.open()

open() == io.open() in Python 3 only. In Python 2 they are different.

While with open() in Python we can obtain an easy-to-use file object with handy read() and write() methods, on the OS level files are accessed using file descriptors (or file handles in Windows). Thus, os.open() should be used implicitly under the hood. I haven't examined Python source code in this regard, but the documentation for the opener parameter, which was added for open() in Python 3.3, says:

A custom opener can be used by passing a callable as opener. The underlying file descriptor for the file object is then obtained by calling opener with (file, flags). opener must return an open file descriptor (passing os.open as opener results in functionality similar to passing None).

So os.open() is the default opener for open(), and we also have the ability to specify a custom wrapper around it if file flags or mode need to be changed. See the documentation for open() for an example of a custom opener, which opens a file relative to a given directory.

wombatonfire
  • 4,585
  • 28
  • 36
5

In Python 2, the built-in open and io.open were different (io.open was newer and supported more things). In Python 3, open and io.open are now the same thing (they got rid of the old built-in open), so you should always use open. Code that needs to be compatible with Python 2 and 3 might have a reason to use io.open.

Below code to validate this.

import io
with io.open("../input/files.txt") as f:
    text = f.read().lower()

with open('../input/files.txt', encoding='utf-8') as f2:
    text2 = f2.read().lower()

print(type(f))
print(type(f2))
# <class '_io.TextIOWrapper'>
# <class '_io.TextIOWrapper'>
RevolverRakk
  • 309
  • 4
  • 10
4

os.open is very similar to open() from C in Unix. You're unlikely to want to use it unless you're doing something much more low-level. It gives you an actual file descriptor (as in, a number, not an object).

io.open is your basic Python open() and what you want to use just about all the time.

Owen
  • 38,836
  • 14
  • 95
  • 125
  • 1
    Does that mean if I take some of my simple C file IO code, prepend `os.` to the `stdio` functions, and change the extension to `.py`, the code will execute without errors? – Gio Borje Aug 28 '11 at 07:20
  • 1
    I highly highly doubt it, but I'd love to see how it goes (just don't break anything). – Owen Aug 28 '11 at 07:34
1

Database and system application developers usually use open instead of fopen as the former provides finer control on when, what and how the memory content should be written to its backing store (i.e., file on disk).

In Unix-like operating system, open is used to open regular file, socket end-point, device, pipe, etc. A positive file descriptor number is returned for every successful open function call. It provides a consistent API and framework to check for event notification, etc on a variety of these objects.

However, fopen is a standard C function and is normally used to open regular file and return a FILE data structure. fopen, actually, will call open eventually. fopen is good enough for normal usage as developers do not need to worry when to flush or sync memory content to the disk and do not need event notification.

yoonghm
  • 4,198
  • 1
  • 32
  • 48
0

os.open() method opens the file file and set various flags according to flags and possibly its mode according to mode.

The default mode is 0777 (octal), and the current unmask value is first masked out.

This method returns the file descriptor for the newly opened file.

While,

io.open() method opens a file, in the mode specified in the string mode. It returns a new file handle, or, in case of errors, nil plus an error message.

Hope this helps

talha2k
  • 24,937
  • 4
  • 62
  • 81