<p>按顺序回答你的问题</p>
<p>“怎么了<code>print(open(file).readlines())</code>?”</p>
<p>好吧,在使用文件对象之后,您将其丢弃,这样您就不能<code>close</code>它了。是的,Python最终会自动关闭您的文件,但以它的方式而不是您的方式。如果你只是在一个shell或终端上玩,这可能很好,因为你的会话可能很短,并且通常不会有任何资源竞争文件。但是,在生产环境中,让文件句柄在脚本的生命周期内保持打开状态可能会对性能造成破坏。</p>
<p>至于创建一个接受一个文件对象并对其进行写入的函数,这就是<code>file.write</code>的本质。假设文件句柄是一个带有方法的对象,而那些幕后的方法将<code>self</code>(即对象)作为第一个参数。所以write本身已经是一个接受文件句柄并对其进行写入的函数!如果需要,可以创建其他函数,但实际上复制默认行为并没有任何实际好处。</p>
<p>假设您的第一个函数看起来像这样:</p>
<pre><code>def write_to(file_handle, text):
return file_handle.write_to(text)
</code></pre>
<p>但是如果我取名为<code>file_handle</code><code>self</code>呢?</p>
<pre><code>def write_to(self, text):
return self.write(text)
</code></pre>
<p>现在它看起来像是一个方法,而不是一个独立的函数。事实上,如果你这样做:</p>
<pre><code>f = open(some_file, 'w') # or 'a' -- some write mode
write_to = f.write
</code></pre>
<p>你有几乎相同的函数(只是绑定到特定的文件句柄)!</p>
<p>作为练习,您还可以在Python中创建自己的上下文管理器(与<code>with</code>语句一起使用)。您可以通过定义<code>__enter__</code>和<code>__exit__</code>来实现这一点。所以从技术上来说,你也可以重新定义:</p>
<pre><code>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()
</code></pre>
<p>然后像这样使用它:</p>
<pre><code>with FileContextManager('hello.txt') as filename:
filename.write('Hi!')
</code></pre>
<p>它也会做同样的事情。</p>
<p>所有这一切的意义只是说,如果需要重新实现它并添加到默认行为中,Python足够灵活,可以完成所有这一切,但在标准情况下,这样做并没有真正的好处。</p>
<hr/>
<p>就您的示例中的程序而言,在这种微不足道的情况下,几乎所有这些方法都没有问题。但是,您缺少在主函数中使用with语句的机会:</p>
<pre><code>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()
</code></pre>
<p>如果要生成以文件句柄作为参数的函数:</p>
<pre><code>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()
</code></pre>
<p>再说一次,你可以用很多不同的方法来做,那么什么对你想要做的最好呢?什么是最可读的?</p>
<p>“我应该在函数中打开一个文件并将指针传递给另一个函数进行写入,还是应该将其声明为模块变量?”</p>
<p>好吧,正如你所看到的,两者都会起作用。这个问题高度依赖于上下文,通常最佳实践要求在最小的合理范围内以最少的时间打开文件。因此,什么需要访问您的文件?如果模块中有很多东西,那么使用模块级变量或类来保存它是一个好主意。同样,在普通情况下,只需使用上面的<code>with</code>。</p>