Python 3.x 如何在追加模式下查找写指针?

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+”模式打开文件。我无法使用“r+”模式,因为如果它不存在,它将不会创建文件。

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+”模式下添加了文档链接,它们仅操作读取指针。我想控制我在哪里写。没有读指针或写指针。只是从读或写的起始点开始的指针而已,我想我在测试它时犯了一个错误。