2015-02-23 47 views
5

我知道文件进行阅读开放最好的办法/写与withPython的打开和读取文件中的一个衬垫

使用,而不是使用

f = open('file.txt', 'w') 
f.write('something') 
f.close() 

我们应该写 -

with open('file.txt', 'w') as f: 
    f.write('something') 

但是如果我想简单地读一个文件呢?我能做到这一点

with open('file.txt') as f: 
    print (f.read()) 

但什么是在下面一行的问题

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

OR

alist = open('file.txt').readlines() 
print (alist) 

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

除此之外 - 我应该打开一个函数中的文件,并将指针传递给其他写入,或者我应该宣布它为全局变量?即

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

def main(): 
    f = open('file.txt', 'w') 
    while somecondition: 
     writeto(f) 
    f. close() 

OR

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

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

def main(): 
    while somecondition: 
     writeto() 

f. close() 
+0

顺便说一句,在直截了当的答案在标题中提出的问题是这样的:'开放(“file.txt的”,“W”)为f:F .write('some text')'用于写入或用'open('file.txt')作为f:contents = f.read()'来读取。 – 2015-02-23 19:26:06

回答

3

解决您的才能问题,

“这有什么错print(open(file).readlines())?”

那么,你使用它后丢弃文件对象,所以你不能close它。是的,Python最终会自动关闭您的文件,但按照其条款而不是您的文件。如果您只是在shell或终端中玩游戏,这可能很好,因为您的会话可能会很短,并且通常不存在任何资源对文件的竞争。但是,在生产环境中,在脚本的整个生命周期中将文件句柄保留为打开状态可能会对性能产生破坏性影响。

至于创建一个接收文件对象并写入它的函数,那么这基本上就是file.write。考虑一个文件句柄是一个包含方法的对象,并且这些场景后面的方法以self(即对象)作为第一个参数。所以编写自己已经是一个函数,它需要一个文件句柄并写入它!如果你愿意,你可以创建其他功能,但你基本上重复了默认行为,而没有实际的好处。

考虑你的第一个功能看起来有点像这样:

def write_to(file_handle, text): 
    return file_handle.write_to(text) 

但如果我叫file_handleself呢?

def write_to(self, text): 
    return self.write(text) 

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

f = open(some_file, 'w') # or 'a' -- some write mode 
write_to = f.write 

你有几乎相同的功能(只是绑定到特定的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() 

,然后用它喜欢:

with FileContextManager('hello.txt') as filename: 
    filename.write('Hi!') 

,它会做同样的事情。

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


就你的例子中的程序而言,在微不足道的情况下,几乎没有任何错误。但是,你缺少与声明在主函数中使用了一个机会:如果你想一个函数,需要一个文件句柄作为参数

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() 

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() 

同样,你可以做很多不同的方式,所以你最想做什么?什么是最可读的?

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

那么,正如你所看到的,要么工作。这个问题与上下文高度相关,通常情况下,最佳实践决定让文件在最短时间内处于最小合理范围。因此,什么需要访问您的文件?如果模块中有很多东西,模块级别的变量或类可能是一个好主意。再次,在微不足道的情况下,就像上面那样使用with

+0

那么你对第二个问题有什么建议。第一个解决方案还是第二 – micheal 2015-02-23 18:41:34

+0

对不起 - 我正在添加第二个例子。我不太清楚你的第二个问题。我的答案的想法是,“这实际上就像读取和写入文件一样简单,而且你提出的所有事情本质上都是默认情况下的。”什么阻止你在主函数中使用'with'语句? – 2015-02-23 18:48:32

+0

您正在提供不同的解决方案。为什么我会在已经有'with'的时候创建'FileContextManager'。我的观点是我不能在同一个函数中执行文件操作,我必须为此创建一个单独的函数,为此我必须使用(全局或参数化)文件对象 – micheal 2015-02-23 19:01:36

-3

问题是你在print和()之间放了一个空格。 此代码的工作好于Python3:

print(open('yourfile.ext').read()) 
+1

这不是父母的帖子所谈论的内容。 – Noelkd 2015-02-23 18:35:36

+0

@ Texom512:它可以在python2和three中都有,也可以不带空格。 – micheal 2015-02-23 18:42:51