Python打开和读取文件一个班轮

mic*_*al 5 python python-2.7 python-3.x

我知道文件打开读/写的最佳方法是使用 with

而不是使用

f = open('file.txt', 'w')
f.write('something')
f.close()
Run Code Online (Sandbox Code Playgroud)

我们应该写 -

with open('file.txt', 'w') as f:
    f.write('something')
Run Code Online (Sandbox Code Playgroud)

但是如果我想简单地读一个文件怎么办?我可以做这个

with open('file.txt') as f:
    print (f.read())
Run Code Online (Sandbox Code Playgroud)

但是下面的问题是什么呢?

print (open('file.txt').read())

要么

alist = open('file.txt').readlines()
print (alist)
Run Code Online (Sandbox Code Playgroud)

执行此语句后会自动关闭文件吗?这是一种标准的写作方式吗?我们应该这样写吗?

除此之外 - 我应该在函数中打开一个文件并将指针传递给其他用于写入,还是应该将其声明为全局变量?即

def writeto(f):
    #do some stuff
    f.write('write stuff')

def main():
   f = open('file.txt', 'w')
   while somecondition:
        writeto(f)
   f. close()
Run Code Online (Sandbox Code Playgroud)

要么

f = open('file.txt', 'w')

def writeto():
    #do some stuff
    f.write('write stuff')

def main():
   while somecondition:
        writeto()

f. close()
Run Code Online (Sandbox Code Playgroud)

Two*_*ist 8

按顺序回答您的问题,

出了什么问题

print(open(file).readlines())
Run Code Online (Sandbox Code Playgroud)

好吧,您在使用文件对象后将其丢弃,这样您就无法使用close它了。是的,Python 最终会自动关闭你的文件,但是按照它的条款而不是你的条款。如果您只是在 shell 或终端中玩,这可能没问题,因为您的会话可能很短,并且通常不会对文件进行任何资源竞争。但是,在生产环境中,在脚本的整个生命周期内保持文件句柄打开可能会对性能造成破坏。

至于创建一个接受文件对象并向其写入的函数,本质上就是这样file.write。考虑文件句柄是一个带有方法的对象,并且这些方法在幕后将self(即对象)作为第一个参数。所以 write 本身已经是一个获取文件句柄并向其写入的函数!如果需要,您可以创建其他函数,但本质上是在重复默认行为,而没有任何实际好处。

考虑一下您的第一个函数看起来有点像这样:

def write_to(file_handle, text):
    return file_handle.write_to(text)
Run Code Online (Sandbox Code Playgroud)

但如果我改名呢file_handle self

def write_to(self, text):
    return self.write(text)
Run Code Online (Sandbox Code Playgroud)

现在它看起来像一个方法而不是一个独立的函数。事实上,如果你这样做:

f = open(some_file, 'w')   # or 'a' -- some write mode
write_to = f.write
Run Code Online (Sandbox Code Playgroud)

你有几乎相同的功能(只是绑定到那个特定的 file_handle)!

作为练习,您还可以在 Python 中创建自己的上下文管理器(与with语句一起使用)。您可以通过定义__enter__和来做到这一点__exit__。所以从技术上来说你也可以重新定义它:

class FileContextManager():
    def __init__(self, filename):
        self.filename = filename
        self._file = None

    def __enter__(self):
        self._file = open(self.filename, 'w')

    def __exit__(self, type, value, traceback):
        self._file.close()
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:

with FileContextManager('hello.txt') as filename:
    filename.write('Hi!')
Run Code Online (Sandbox Code Playgroud)

它也会做同样的事情。

所有这一切的要点只是说,如果您需要重新实现它并添加到默认行为,Python 足够灵活,可以完成所有这些工作,但在标准情况下,这样做没有真正的好处。


就您示例中的程序而言,在简单的情况下,几乎所有这些方法都没有任何问题。但是,您错过了在主函数中使用 with 语句的机会:

def main():
    with open('file.txt') as filename:
        while some_condition:
            filename.write('some text')
    # file closed here after we fall off the loop then the with context

if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

如果您想创建一个将文件句柄作为参数的函数:

def write_stuff(file_handle, text):
    return file_handle.write(text)

def main():
    with open('file.txt', 'w') as filename:
        while some_condition:
            write_stuff(filename, 'some text')
    # file closed here after we fall off the loop then the with context

if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

同样,您可以通过多种不同的方式来完成此操作,那么什么最适合您想要做的事情呢?什么是最具可读性的?

我应该在函数中打开一个文件并将指针传递给其他文件进行写入还是应该将其声明为模块变量?

嗯,正如您所看到的,两者都可以。这个问题高度依赖于上下文,通常最佳实践要求在最小的合理范围内打开文件最短的时间。那么,什么需要访问您的文件呢?如果模块中有很多东西,也许用模块级变量或类来保存它是一个好主意。同样,在简单的情况下,只需按with上述方式使用即可。