简体   繁体   English

被python文件模式“w+”搞糊涂了

[英]Confused by python file mode “w+”

From the doc ,文档中

Modes 'r+', 'w+' and 'a+' open the file for updating (note that 'w+' truncates the file).模式“r+”、“w+”和“a+”打开文件进行更新(注意“w+”会截断文件)。 Append 'b' to the mode to open the file in binary mode, on systems that differentiate between binary and text files;在区分二进制和文本文件的系统上,将“b”附加到模式以二进制模式打开文件; on systems that don't have this distinction, adding the 'b' has no effect.在没有这种区别的系统上,添加“b”无效。

and here在这里

w+ : Opens a file for both writing and reading. w+ :打开文件进行读写。 Overwrites the existing file if the file exists.如果文件存在,则覆盖现有文件。 If the file does not exist, creates a new file for reading and writing.如果文件不存在,则创建一个新文件进行读写。

But, how to read a file open with w+ ?但是,如何读取用w+打开的文件?

Here is a list of the different modes of opening a file:以下是打开文件的不同模式的列表:

  • r r

    Opens a file for reading only.以只读方式打开文件。 The file pointer is placed at the beginning of the file.文件指针位于文件的开头。 This is the default mode.这是默认模式。

  • rb RB

    Opens a file for reading only in binary format.以二进制格式打开一个只读文件。 The file pointer is placed at the beginning of the file.文件指针位于文件的开头。 This is the default mode.这是默认模式。

  • r+ r+

    Opens a file for both reading and writing.打开文件以进行读取和写入。 The file pointer will be at the beginning of the file.文件指针将位于文件的开头。

  • rb+ RB+

    Opens a file for both reading and writing in binary format.打开一个文件,以二进制格式进行读写。 The file pointer will be at the beginning of the file.文件指针将位于文件的开头。

  • w

    Opens a file for writing only.打开一个仅用于写入的文件。 Overwrites the file if the file exists.如果文件存在,则覆盖该文件。 If the file does not exist, creates a new file for writing.如果文件不存在,则创建一个新文件进行写入。

  • wb

    Opens a file for writing only in binary format.打开一个仅以二进制格式写入的文件。 Overwrites the file if the file exists.如果文件存在,则覆盖该文件。 If the file does not exist, creates a new file for writing.如果文件不存在,则创建一个新文件进行写入。

  • w+ w+

    Opens a file for both writing and reading.打开文件以进行写入和读取。 Overwrites the existing file if the file exists.如果文件存在,则覆盖现有文件。 If the file does not exist, creates a new file for reading and writing.如果文件不存在,则创建一个新文件进行读写。

  • wb+白+

    Opens a file for both writing and reading in binary format.以二进制格式打开一个文件进行读写。 Overwrites the existing file if the file exists.如果文件存在,则覆盖现有文件。 If the file does not exist, creates a new file for reading and writing.如果文件不存在,则创建一个新文件进行读写。

  • a一种

    Opens a file for appending.打开要追加的文件。 The file pointer is at the end of the file if the file exists.如果文件存在,则文件指针位于文件末尾。 That is, the file is in the append mode.也就是说,文件处于追加模式。 If the file does not exist, it creates a new file for writing.如果文件不存在,它会创建一个新文件用于写入。

  • ab AB

    Opens a file for appending in binary format.打开一个文件以二进制格式追加。 The file pointer is at the end of the file if the file exists.如果文件存在,则文件指针位于文件末尾。 That is, the file is in the append mode.也就是说,文件处于追加模式。 If the file does not exist, it creates a new file for writing.如果文件不存在,它会创建一个新文件用于写入。

  • a+一个+

    Opens a file for both appending and reading.打开一个文件以进行追加和读取。 The file pointer is at the end of the file if the file exists.如果文件存在,则文件指针位于文件末尾。 The file opens in the append mode.文件以追加模式打开。 If the file does not exist, it creates a new file for reading and writing.如果文件不存在,它会创建一个新文件进行读写。

  • ab+ ab+

    Opens a file for both appending and reading in binary format.打开一个文件,以二进制格式进行追加和读取。 The file pointer is at the end of the file if the file exists.如果文件存在,则文件指针位于文件末尾。 The file opens in the append mode.文件以追加模式打开。 If the file does not exist, it creates a new file for reading and writing.如果文件不存在,它会创建一个新文件进行读写。

All file modes in Python Python中的所有文件模式

  • r for reading r阅读
  • r+ opens for reading and writing (cannot truncate a file) r+以读写方式打开(无法截断文件)
  • w for writing w用于写作
  • w+ for writing and reading (can truncate a file) w+用于写入和读取(可以截断文件)
  • rb for reading a binary file. rb用于读取二进制文件。 The file pointer is placed at the beginning of the file.文件指针位于文件的开头。
  • rb+ reading or writing a binary file rb+读取或写入二进制文件
  • wb+ writing a binary file wb+写入二进制文件
  • a+ opens for appending a+打开追加
  • ab+ Opens a file for both appending and reading in binary. ab+打开一个文件以二进制追加和读取。 The file pointer is at the end of the file if the file exists.如果文件存在,则文件指针位于文件末尾。 The file opens in the append mode.文件以追加模式打开。
  • x open for exclusive creation, failing if the file already exists (Python 3) x打开独占创建,如果文件已经存在则失败(Python 3)

Let's say you're opening the file with a with statement like you should be.假设您使用with语句打开文件,就像您应该的那样。 Then you'd do something like this to read from your file:然后你会做这样的事情来从你的文件中读取:

with open('somefile.txt', 'w+') as f:
    # Note that f has now been truncated to 0 bytes, so you'll only
    # be able to read data that you write after this point
    f.write('somedata\n')
    f.seek(0)  # Important: return to the top of the file before reading, otherwise you'll just read an empty string
    data = f.read() # Returns 'somedata\n'

Note the f.seek(0) -- if you forget this, the f.read() call will try to read from the end of the file, and will return an empty string.注意f.seek(0) —— 如果你忘记了这一点, f.read()调用将尝试从文件末尾读取,并返回一个空字符串。

r for read r读取

w for write w为写

r+ for read/write without deleting the original content if file exists, otherwise raise exception如果文件存在,则r+用于读/写而不删除原始内容,否则引发异常

w+ for delete the original content then read/write if file exists, otherwise create the file w+用于删除原始内容然后读/写如果文件存在,否则创建文件

For example,例如,

>>> with open("file1.txt", "w") as f:
...   f.write("ab\n")
... 
>>> with open("file1.txt", "w+") as f:
...   f.write("c")
... 

$ cat file1.txt 
c$
>>> with open("file2.txt", "r+") as f:
...   f.write("ab\n")
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: 'file2.txt'

>>> with open("file2.txt", "w") as f:
...   f.write("ab\n")
... 
>>> with open("file2.txt", "r+") as f:
...   f.write("c")
... 

$ cat file2.txt 
cb
$

Both seems to be working same but there is a catch.两者似乎都在工作,但有一个问题。

r+ :- r + :-

  • Open the file for Reading and Writing打开文件进行读写
  • Once Opened in the beginning file pointer will point to 0一旦 Opened 在开始文件指针将指向 0
  • Now if you will want to Read then it will start reading from beginning现在,如果您想阅读,它将从头开始阅读
  • if you want to Write then start writing, But the write process will begin from pointer 0. So there would be overwrite of characters, if there is any如果你想写就开始写,但是写过程将从指针 0 开始。所以会有字符覆盖,如果有的话
  • In this case File should be present, either will FileNotFoundError will be raised.在这种情况下 File 应该存在,或者FileNotFoundError将被引发。

w+ :- w+ :-

  • Open the file for Reading and Writing打开文件进行读写
  • If file exist, File will be opened and all data will be erased,如果文件存在,将打开文件并删除所有数据,
  • If file does not exist, then new file will be created如果文件不存在,则将创建新文件
  • In the beginning file pointer will point to 0 (as there is not data)在开始文件指针将指向 0(因为没有数据)
  • Now if you want to write something, then write现在如果你想写点什么,那就写
  • File pointer will be Now pointing to end of file (after write process)文件指针现在指向文件末尾(写入过程后)
  • If you want to read the data now, seek to specific point.如果要现在读取数据,请寻找特定点。 (for beginning seek(0)) (开始寻找(0))

So, Overall saying both are meant to open the file to read and write but difference is whether we want to erase the data in the beginning and then do read/write or just start as it is.因此,总的来说,两者都是为了打开文件进行读写,但区别在于我们是要在开始时擦除数据然后进行读/写还是按原样开始。

abc.txt - in beginning abc.txt - 开头

1234567
abcdefg
0987654
1234

Code for r+

with open('abc.txt', 'r+') as f:      # abc.txt should exist before opening
    print(f.tell())                   # Should give ==> 0
    f.write('abcd')                   
    print(f.read())                   # Pointer is pointing to index 3 => 4th position
    f.write('Sunny')                  # After read pointer is at End of file

Output

0
567
abcdefg
0987654
1234

abc.txt - After Run: abc.txt - 运行后:

abcd567
abcdefg
0987654
1234Sunny

Resetting abc.txt as initial将 abc.txt 重置为初始值

Code for w+

with open('abc.txt', 'w+') as f:     
    print(f.tell())                   # Should give ==> 0
    f.write('abcd')                   
    print(f.read())                   # Pointer is pointing to index 3 => 4th position
    f.write('Sunny')                  # After read pointer is at End of file

Output

0


abc.txt - After Run: abc.txt - 运行后:

abcdSunny

该文件被截断,因此您可以调用read() (不会引发异常,与使用 'w' 打开时不同)但您将获得一个空字符串。

I suspect there are two ways to handle what I think you'r trying to achieve.我怀疑有两种方法可以处理我认为您想要实现的目标。

1) which is obvious, is open the file for reading only, read it into memory then open the file with t, then write your changes. 1)这是显而易见的,打开文件只读,将其读入内存,然后用 t 打开文件,然后写入您的更改。

2) use the low level file handling routines: 2) 使用低级文件处理例程:

# Open file in RW , create if it doesn't exist. *Don't* pass O_TRUNC
 fd = os.open(filename, os.O_RDWR | os.O_CREAT)

Hope this helps..希望这可以帮助..

Actually, there's something wrong about all the other answers about r+ mode.实际上,关于r+模式的所有其他答案都有问题。

test.in file's content: test.in文件内容:

hello1
ok2
byebye3

And the py script's :和 py 脚本的:

with open("test.in", 'r+')as f:
    f.readline()
    f.write("addition")

Execute it and the test.in 's content will be changed to :执行它, test.in的内容将更改为:

hello1
ok2
byebye3
addition

However, when we modify the script to :但是,当我们将脚本修改为:

with open("test.in", 'r+')as f:
    f.write("addition")

the test.in also do the respond: test.in也做回应:

additionk2
byebye3

So, the r+ mode will allow us to cover the content from the beginning if we did't do the read operation.因此,如果我们不进行读取操作, r+模式将允许我们从头开始覆盖内容。 And if we do some read operation, f.write() will just append to the file.如果我们做一些读操作, f.write()只会追加到文件中。

By the way, if we f.seek(0,0) before f.write(write_content) , the write_content will cover them from the positon(0,0).顺便说一下,如果我们在f.write(write_content) f.seek(0,0)之前f.seek(0,0)f.write(write_content) f.seek(0,0)覆盖它们。

I was sooo confusing too... But may be my answer will help someone.我也很困惑......但我的回答可能会对某人有所帮助。 I assume that you want to leverage the ability of 'w+' mode to create the file if it doesn't exist.我假设您想利用“w+”模式的能力来创建不存在的文件。

Indeed, only w, w+, a, a+ can create if the file doesn't exist.事实上,如果文件不存在,只有 w, w+, a, a+ 可以创建。

But if you need to read the data of the file (the scenario when the file with data did exist) you can't do it with w+ out of the box because it truncates the file.但是,如果您需要读取文件的数据(包含数据的文件确实存在的情况),则无法使用 w+ 开箱即用,因为它会截断文件。 Oops, you didn't mean that!哎呀,你不是那个意思!

So, probably, your best friend would be a+ with file.seek(0):所以,可能你最好的朋友会是一个 + 和 file.seek(0):

with open('somefile.txt', 'a+') as f:
    f.seek(0)
    for line in f:
        print(f.readline())

正如h4z3提到的,对于实际使用,有时你的数据太大而不能直接加载所有东西,或者你有一个生成器,或者实时传入的数据,你可以使用 w+ 存储在一个文件中,稍后阅读。

Here is the list might be helpful这是列表可能会有所帮助

Character Meaning字符含义

'r' - open for reading (default) 'r' - 打开以供阅读(默认)

'w' - open for writing, truncating the file first 'w' - 打开写入,首先截断文件

'x' - open for exclusive creation, failing if the file already exists 'x' - 打开独占创建,如果文件已经存在则失败

'a' - open for writing, appending to the end of the file if it exists 'a' - 为写入而打开,如果文件存在则附加到文件末尾

'b' - binary mode 'b' - 二进制模式

't' - text mode (default) 't' - 文本模式(默认)

'+' - open for updating (reading and writing) '+' - 打开更新(读取和写入)

The default mode is 'r' (open for reading text, synonym of 'rt').默认模式是“r”(打开阅读文本,“rt”的同义词)。 Modes 'w+' and 'w+b' open and truncate the file.模式 'w+' 和 'w+b' 打开并截断文件。 Modes 'r+' and 'r+b' open the file with no truncation.模式 'r+' 和 'r+b' 不截断地打开文件。

Reference: https://docs.python.org/3/library/functions.html#open参考: https : //docs.python.org/3/library/functions.html#open

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM