被 python 文件模式“w+”[重复] 弄糊涂了

Confused by python file mode "w+" [duplicate]

提问人:holys 提问时间:4/25/2013 更新时间:7/14/2021 访问量:475804

问:

文档中,

模式“r+”、“w+”和“a+”打开文件进行更新(请注意,“w+”会截断文件)。在区分二进制文件和文本文件的系统上,将“b”附加到以二进制模式打开文件的模式;在没有这种区别的系统上,添加“b”不起作用。

这里

w+ :打开一个文件进行写入和读取。如果现有文件存在,则覆盖该文件。如果该文件不存在,则创建一个用于读取和写入的新文件。

但是,如何读取用 ?w+

python 文件 io

评论

36赞 Ritwik 1/5/2018
我发现这张图非常有用。

答:

2赞 Elazar 4/25/2013 #1

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

167赞 rmunn 4/25/2013 #2

假设您正在打开文件,并带有应有的语句。然后,您可以执行如下操作来读取文件中的内容:with

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'

请注意 -- 如果您忘记了这一点,调用将尝试从文件末尾读取,并将返回一个空字符串。f.seek(0)f.read()

评论

3赞 Nasif Imtiaz Ohi 1/6/2018
“截断为 0 字节”是什么意思?
31赞 rmunn 1/6/2018
@NasifImtiazOhi - Python 文档说,如果文件存在,它将“覆盖现有文件”。因此,只要您打开一个带有 的文件,它现在就是一个空文件:它包含 0 个字节。如果它曾经包含数据,则该数据已被截断 - 被切断并丢弃 - 现在文件大小为 0 字节,因此您无法读取在使用 打开文件之前存在的任何数据。如果您确实想读取以前的数据并添加到其中,则应使用 而不是 。w+w+w+r+w+
0赞 Beqa Bukhradze 7/2/2018
如何在顶部添加新数据?
3赞 rmunn 7/2/2018
@BeqaBukhradze - 如果您有问题,请单击“提问”按钮,数百人将看到该问题。不要只点击“添加评论”按钮,只有一两个人会看到它。
0赞 Psychzander 8/4/2020
@BeqaBukhadraze使用“A”模式
2赞 Dory Zidon 4/25/2013 #3

我怀疑有两种方法可以处理我认为你想要实现的目标。

1)很明显,打开文件仅供读取,将其读入内存,然后用t打开文件,然后写入更改。

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)

希望这会有所帮助..

评论

0赞 Smart Manoj 6/18/2019
那做什么r+
172赞 Alok Agarwal 4/25/2013 #4

Python 中的所有文件模式

  • r供阅读
  • r+打开进行读取和写入(无法截断文件)
  • w用于写作
  • w+用于写入和读取(可以截断文件)
  • rb用于读取二进制文件。文件指针位于文件的开头。
  • rb+读取或写入二进制文件
  • wb+编写二进制文件
  • a+打开以追加
  • ab+打开一个文件,以二进制形式追加和读取。如果文件存在,则文件指针位于文件的末尾。文件将在追加模式下打开。
  • x打开以独占方式创建,如果文件已存在,则失败 (Python 3)

评论

5赞 abarnert 8/4/2014
这还不是所有的模式。例如,它忽略了 和 ,更不用说 2.x 中的模式和 3.x 中的模式(它们都可以与除 之外的所有内容结合使用)。rbwbUtb
1赞 Martin 10/7/2014
r+ 和 w+ 之间的区别在于 w+ 在打开文件时会截断文件。但是您可以在两种模式下手动截断它。
2赞 Celeritas 7/18/2015
这个答案与@200 OK给出的答案不一致,例如,是否也从文件中读取?wb+
0赞 Alok Agarwal 8/12/2015
@Celeritas wb 表示文件以二进制模式打开以进行写入。在 Unix 系统(Linux、Mac OS X 等)上,二进制模式不做任何事情 - 它们处理文本文件的方式与处理任何其他文件的方式相同。但是,在 Windows 上,文本文件是用略微修改的行尾编写的。这在处理实际的二进制文件(如 exe 或 jpg 文件)时会导致严重问题。因此,在打开不应该是文本的文件时,即使在 Unix 中,也应该使用 wb 或 rb。仅对文本文件使用纯 w 或 r。
0赞 Laurent LAPORTE 10/20/2016
在 Python 3 中,还有“x”打开模式:打开以独占创建,如果文件已经存在,则失败。请参阅文档中的 open 函数。
556赞 Kousik 5/9/2014 #5

以下是打开文件的不同模式的列表:

  • r

    打开仅供读取的文件。文件指针位于文件的开头。这是默认模式。

  • RB型

    打开仅供二进制格式读取的文件。文件指针位于文件的开头。这是默认模式。

  • R+系列

    打开一个文件进行读取和写入。文件指针将位于文件的开头。

  • RB+(RB+)

    以二进制格式打开用于读取和写入的文件。文件指针将位于文件的开头。

  • w

    打开仅供写入的文件。如果文件存在,则覆盖该文件。如果该文件不存在,请创建一个新文件进行写入。

  • 工 务 局

    打开仅以二进制格式写入的文件。如果文件存在,则覆盖该文件。如果该文件不存在,请创建一个新文件进行写入。

  • W+系列

    打开文件以进行写入和读取。如果现有文件存在,则覆盖该文件。如果该文件不存在,则创建一个用于读取和写入的新文件。

  • 免疫印迹 +

    以二进制格式打开文件进行写入和读取。如果现有文件存在,则覆盖该文件。如果该文件不存在,则创建一个用于读取和写入的新文件。

  • 一个

    打开要追加的文件。如果文件存在,则文件指针位于文件的末尾。也就是说,文件处于追加模式。如果该文件不存在,它将创建一个新文件进行写入。

  • 血型

    打开一个文件以二进制格式追加。如果文件存在,则文件指针位于文件的末尾。也就是说,文件处于追加模式。如果该文件不存在,它将创建一个新文件进行写入。

  • A+级

    打开文件以进行追加和读取。如果文件存在,则文件指针位于文件的末尾。文件将在追加模式下打开。如果该文件不存在,它将创建一个用于读取和写入的新文件。

  • AB+(英语:AB

    以二进制格式打开用于追加和读取的文件。如果文件存在,则文件指针位于文件的末尾。文件将在追加模式下打开。如果该文件不存在,它将创建一个用于读取和写入的新文件。

评论

30赞 abarnert 8/4/2014
@Humdinger:否,创建一个新文件或截断一个现有文件,然后打开它进行读写; 打开现有文件,而不截断它以进行读取和写入。非常不同。w+r+
1赞 abarnert 8/4/2014
此外,与@AlokAgarwal的答案一样,这声称是模式的详尽列表,但事实并非如此。
1赞 rmunn 10/3/2014
给出一个详尽的模式列表是相当愚蠢的,因为它们的功能更像是一个具有多个参数的函数。、 或 是排他性的,但可以添加到其中任何一个中,也可以 或 ...这是一场组合爆炸。rwab+U
4赞 iggy 7/27/2015
rb不是默认模式,引用:docs.python.org/2/library/functions.html#openThe most commonly-used values of mode are 'r' for reading, 'w' for writing (truncating the file if it already exists), and 'a' for appending (which on some Unix systems means that all writes append to the end of the file regardless of the current seek position). If mode is omitted, it defaults to 'r'
3赞 András Aszódi 9/1/2015
也许我们可以添加“x”模式,又名“独占创建”:如果文件不存在,则创建文件(用于写入),如果不存在,则引发 FileExistsError。
2赞 Find 7/29/2016 #6

实际上,所有其他关于模式的答案都有问题。r+

test.in文件内容:

hello1
ok2
byebye3

而 py 脚本的:

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

执行它,的内容将更改为:test.in

hello1
ok2
byebye3
addition

但是,当我们将脚本修改为:

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

也做响应:test.in

additionk2
byebye3

因此,如果我们不执行读取操作,该模式将允许我们从头开始覆盖内容。如果我们做一些读取操作,将只附加到文件中。r+f.write()

顺便说一句,如果我们之前 ,write_content将从 positon(0,0) 覆盖它们。f.seek(0,0)f.write(write_content)

0赞 Smart Manoj #7

正如 h4z3 所提到的, 为了实际使用, 有时你的数据太大而无法直接加载所有内容,或者你有一个生成器,或者实时传入的数据,你可以使用 w+ 存储在文件中并稍后读取。

16赞 GraceMeng 7/18/2019 #8

r供阅读

w用于写入

r+如果文件存在,则在不删除原始内容的情况下进行读/写,否则引发异常

w+对于删除原始内容,如果文件存在,则读/写,否则创建文件

例如

>>> 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
$
8赞 madhukant dinker 11/18/2020 #9

两者似乎都工作相同,但有一个问题。

r+ :-

  • 打开文件进行读取和写入
  • 一旦在开始文件中打开,指针将指向 0
  • 现在,如果您想阅读,那么它将从头开始阅读
  • 如果要写入则开始写入,但写入过程将从指针 0 开始。因此,如果有的话,字符将被覆盖
  • 在这种情况下,文件应该存在,将引发 FileNotFoundError

w+ :-

  • 打开文件进行读取和写入
  • 如果文件存在,文件将被打开并删除所有数据,
  • 如果文件不存在,则将创建新文件
  • 在开始时,文件指针将指向 0(因为没有数据)
  • 现在,如果你想写点什么,那就写吧
  • 文件指针将指向文件末尾(写入过程后)
  • 如果要立即读取数据,请查找特定点。(用于开始搜索(0))

因此,总的来说,两者都是为了打开文件进行读取和写入,但区别在于我们是否要在开始时擦除数据,然后进行读/写或按原样开始。

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- 运行后:

abcd567
abcdefg
0987654
1234Sunny

将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- 运行后:

abcdSunny
1赞 SSV 1 3/6/2021 #10

以下是可能会有所帮助的列表

字符含义

'r' - 打开阅读(默认)

'w' - 打开进行写入,首先截断文件

“x” - 打开以独占方式创建,如果文件已存在,则失败

'a' - 打开以供写入,如果存在,则追加到文件末尾

'b' - 二进制模式

't' - 文本模式(默认)

'+' - 打开更新(读取和写入)

默认模式为“r”(打开用于阅读文本,“rt”的同义词)。模式“w+”和“w+b”打开并截断文件。模式“r+”和“r+b”打开文件时不会截断。

编号:https://docs.python.org/3/library/functions.html#open

1赞 Andrew Anderson 7/14/2021 #11

我也很困惑......但也许我的答案会帮助某人。 我假设您想利用“w+”模式的功能来创建文件(如果它不存在)。

事实上,如果文件不存在,则只能创建 w、w+、a、a+。

但是,如果您需要读取文件的数据(包含数据的文件确实存在的情况),则无法使用开箱即用的 w+ 来执行此操作,因为它会截断文件。哎呀,你不是那个意思!

所以,你最好的朋友可能是 file.seek(0) 的 a+:

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