繁体   English   中英

将文件写入代码减少到一行时,文件关闭错误,[AttributeError:'int'对象没有属性'close']

[英]File close error, [AttributeError: 'int' object has no attribute 'close'] when reducing file write code to a single line

通过Zed Shaw的书练习17 [关于将一个文件复制到另一个文件],他减少了这两行代码

in_file = open(from_file)
indata = in_file.read()

合二为一:

indata = open(from_file).read()

他写的还有一段代码

out_file = open(to_file, 'w')
out_file.write(indata)

所以我把它减少到与上面相同的一行:

out_file = open(to_file, 'w').write(indata)

这似乎工作正常,但当我关闭out_file出现错误:

Traceback (most recent call last):
  File "filesCopy.py", line 27, in <module>
    out_file.close()
AttributeError: 'int' object has no attribute 'close'

我无法掌握发生了什么以及close()在这里工作的程度如何?

write方法返回文件写入的字符数,这是一个整数而不是文件对象,因此没有close方法。

In [6]: a = open('test', 'w')          
In [7]: t = a.write('ssss')
In [8]: t
Out[8]: 4

此外,仅当您不希望与文件进行任何进一步交互时,才建议直接在open()上调用I / O方法。 此外,处理文件对象的最恰当方法是使用with语句在块的末尾自动关闭文件,并且不需要手动调用close()

with open('filename', 'w') as f:
    # do something

以下通常是更好的方法,包括阅读和写作:

with open("myfile.txt", "w") as f:
    # do something with f

无需使用此代码关闭f。

使用代码val = open(to_file, 'w').write(indata) “val”将是write函数的返回值,而不是open函数。

这两者并不相同。 如果你写out_file = open(to_file, 'w').write(indata) ,你已经隐式写了:

# equivalent to second code sample
temp = open(to_file, 'w')
out_file = temp.write(indata)

现在我们可以在write()文档中看到:

f.write(string)f.write(string)的内容写入文件, 返回写入的字符数

所以它返回一个整数。 所以在你的第二个例子中, out_file 不是文件处理程序,而是整数。 在代码中,您可以使用out_file.close()来关闭out_file文件处理程序。 但是由于out_file不再是文件处理程序,因此在此处调用close是没有意义的。

然而,通过使用上下文,您不再需要自己执行.close() ,因此可能更优雅:

with open(to_file, 'w') as out_file:
    out_file.write(indata)

允许书籍本身的减少(至少在语义上,最好使用上下文管理器),因为作者可能永远不会明确地关闭文件句柄。

read()函数读取文件然后返回文件内容,因此当您将indata分配给read()它会分配返回的文件内容。 不同之处在于write()函数返回写入的字符数,因此outdata现在是一个int对象。

在此处阅读更多相关信息: https//docs.python.org/3.6/tutorial/inputoutput.html

因此,您不能将write()函数组合成一行,并且希望在之后关闭引用的文件对象,这是灾难性的。

首选方法是使用with块。 有关详细信息,请参阅@ Willem的答案。

当你阅读那本书的第64页时,作者“Zed”已经澄清了。 请阅读以下内容:

当我尝试缩短此脚本时,我在最后关闭文件时出错。 你可能做了类似这样的事情,indata = open(from_file).read(),这意味着你到达脚本末尾时不需要执行in_file.close()。 一条线运行后,它应该已经被Python关闭。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM