被python文件模式迷惑& w+"

医生

模式'r+', 'w+'和'a+'打开文件进行更新(注意'w+'会截断文件)。在区分二进制文件和文本文件的系统上,在模式后追加'b'以二进制模式打开文件;在没有这种区别的系统中,添加“b”没有任何效果。

在这里

w+:打开文件进行读写操作。如果文件存在,则覆盖现有文件。如果该文件不存在,则创建一个新文件进行读写。

但是,如何用w+读取打开的文件呢?

451987 次浏览

文件被截断了,所以你可以调用read()(不会引发异常,不像使用'w'打开时那样),但你会得到一个空字符串。

假设你像你应该的那样用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()调用将尝试从文件末尾读取,并返回一个空字符串。

我认为有两种方法可以解决你想要达到的目标。

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)

希望这能有所帮助。

Python中的所有文件模式

  • r用于读取
  • r+为读写打开(不能截断文件)
  • w用于写入
  • w+用于写入和读取(可以截断文件)
  • rb用于读取二进制文件。文件指针位于文件的开头。
  • rb+读取或写入二进制文件
  • wb+写入二进制文件
  • a+打开用于追加
  • ab+以二进制形式打开文件进行追加和读取。如果文件存在,则文件指针位于文件的末尾。文件以追加模式打开。
  • x打开独占创建,如果文件已经存在则失败(Python 3)

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

  • <标题> r

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

    李< /引用> < / >
  • <标题> rb

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

    李< /引用> < / >
  • <标题> r +

    打开文件进行读写。文件指针将位于文件的开头。

    李< /引用> < / >
  • <标题> rb +

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

    李< /引用> < / >
  • <标题> w

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

    李< /引用> < / >
  • <标题>白平衡

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

    李< /引用> < / >
  • <标题> w +

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

    李< /引用> < / >
  • <标题> wb +

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

    李< /引用> < / >
  • < h1 >

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

    李< /引用> < / >
  • <标题> ab

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

    李< /引用> < / >
  • <标题> a +

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

    李< /引用> < / >
  • <标题> ab +

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

    李< /引用> < / >

实际上,关于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+模式将允许我们从头覆盖内容。如果我们做一些读操作,__abc1只会附加到文件中。

顺便说一下,如果在f.write(write_content)之前f.seek(0,0), write_content将从位置(0,0)开始覆盖它们。

h4z3所述, 在实际应用中, 有时你的数据太大,不能直接加载所有内容,或者你有一个生成器,或者实时传入的数据,你可以使用w+存储在一个文件中,然后读取

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
$

两者似乎都是一样的,但有一个问题。

r +: -

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

w +: -

  • 打开文件进行读写
  • 如果文件存在,文件将被打开,所有数据将被擦除,
  • 如果文件不存在,则创建新文件
  • 在开始文件中指针将指向0(因为没有数据)
  • 现在如果你想写点什么,那就写吧
  • 文件指针现在指向文件的末尾(写入过程之后)
  • 如果你现在想读取数据,请寻找特定的点。(用于开始seek(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

下面的清单可能会有帮助

字符 意义

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

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

'x' -打开独占创建,如果文件已经存在则失败

'a' -打开用于写入,如果存在则附加到文件的末尾

'b' -二进制模式

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

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

默认模式是'r'(用于阅读文本,'rt'的同义词)。模式'w+'和'w+b'打开并截断文件。模式'r+'和'r+b'打开文件,没有截断。

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

我也很困惑…但也许我的答案会帮助到别人。 我假设您想利用'w+'模式来创建不存在的文件

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

但是如果你需要读取文件的数据(当有数据的文件确实存在的情况下),你不能用w+开箱即用,因为它会截断文件。哎呀,你不是那个意思!

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

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