开发者

What's the difference between io.open() and os.open() on Python?

开发者 https://www.devze.com 2023-04-01 10:16 出处:网络
I realised that the open() function I\'ve been using was an alias to io.open() and that importing * from os would overshadow that. 开发者_如何学JAVA

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

开发者_如何学JAVA

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


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


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.


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.


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.


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'>


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.


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

0

精彩评论

暂无评论...
验证码 换一张
取 消