Python 3.x 如何在追加模式下查找写指针?
我试图打开一个文件,读取它的内容,然后使用前面读取的内容写入它。我正在以“a+”模式打开文件。我无法使用“r+”模式,因为如果它不存在,它将不会创建文件。Python 3.x 如何在追加模式下查找写指针?,python-3.x,file-handling,Python 3.x,File Handling,我试图打开一个文件,读取它的内容,然后使用前面读取的内容写入它。我正在以“a+”模式打开文件。我无法使用“r+”模式,因为如果它不存在,它将不会创建文件。a+将把指针放在文件的末尾 您可以使用tell()保存它,以便以后编写 然后使用seek(0,0)返回到开始读取的文件 默认打开 使用默认的a(+)选项是不可能的,如文档中提供的: ''mode是一个可选字符串,用于指定文件所处的模式 打开了。它默认为“r”,这意味着可以在文本中阅读 模式其他常用值是用于写入的“w”(如果需要,则截断文件)
a+
将把指针放在文件的末尾
您可以使用tell()
保存它,以便以后编写
然后使用seek(0,0)
返回到开始读取的文件
默认打开
使用默认的a(+)
选项是不可能的,如文档中提供的:
''mode是一个可选字符串,用于指定文件所处的模式
打开了。它默认为“r”,这意味着可以在文本中阅读
模式其他常用值是用于写入的“w”(如果需要,则截断文件)
它已经存在),“x”用于创建和写入新文件,和
“a”表示追加(在某些Unix系统上,这意味着所有写入
附加到文件末尾,而不考虑当前搜索位置)。“”
可供替代的 使用默认的open,这是不可能的。但是我们当然可以创建自己的文件处理程序,它将在
r
和r+
模式下创建一个不存在的文件
与open(filename,'r+',*args,**kwargs)
完全相同的最简单的工作示例是:
import os
class FileHandler:
def __init__(self, filename, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True):
self.filename = filename
self.mode = mode
self.kwargs = dict(buffering=buffering, encoding=encoding, errors=errors, newline=newline, closefd=closefd)
if self.kwargs['buffering'] is None:
del self.kwargs['buffering']
def __enter__(self):
if self.mode.startswith('r') and not os.path.exists(self.filename):
with open(self.filename, 'w'): pass
self.file = open(self.filename, self.mode, **self.kwargs)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
self.file.close()
现在,当您使用以下代码时:
with FileHandler("new file.txt", "r+") as file:
file.write("First line\n")
file.write("Second line\n")
file.seek(0, 0)
file.write("Third line\n")
当它不存在时,它将生成一个新文件new file.txt
,上下文如下:
Third line
Second line
如果使用打开
,如果文件不存在,您将收到文件NotFoundError
笔记
- 我仅在模式以
开始时创建一个新文件,所有其他文件都将按照正常的r
功能处理打开
- 由于某种原因,将
直接传递到buffering=None
函数会导致它崩溃,并出现open
,因此如果它是TypeError:integer是必需的(get type NoneType)
,我必须将其从关键字参数中删除。即使它是文档中的默认参数(如果有人知道原因,请告诉我)None
file = FileHandler("new file.txt", "r+")
file.seek(0, 0)
file.write("Welcome")
file.close()
为了支持所有打开的
用例,可以使用\uuuu getattr\uuuu
对上述类进行如下调整:
import os
class FileHandler:
def __init__(self, filename, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True):
self.filename = filename
self.mode = mode
self.kwargs = dict(buffering=buffering, encoding=encoding, errors=errors, newline=newline, closefd=closefd)
if self.kwargs['buffering'] is None:
del self.kwargs['buffering']
if self.mode.startswith('r') and not os.path.exists(self.filename):
with open(self.filename, 'w'): pass
self.file = open(self.filename, self.mode, **self.kwargs)
def __enter__(self):
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
self.file.close()
def __getattr__(self, item):
if hasattr(self.file, item):
return getattr(self.file, item)
raise AttributeError(f"{type(self).__name__}, doesn't have the attribute {item!r}")
如果您知道如何使用
r+
解决它,为什么不在该部分之前使用os.path.exists()
检查文件是否存在,如果不存在,则检查文件是否存在。@Thymen我现在正在这样做,但我想知道您如何做到这一点。在某些情况下它会很有用。我找不到这些函数的任何文档,你能给我指一下吗?谢谢。我把它误称为C fseek和ftell。在python中,它只是seek
和tell
。在“a+”模式下添加了文档链接,它们仅操作读取指针。我想控制我在哪里写。没有读指针或写指针。只是从读或写的起始点开始的指针而已,我想我在测试它时犯了一个错误。