当我通过strace
运行时,以下Python 3代码对我(至少对我来说)表现出一些奇怪的行为:
import os
import sys
if len(sys.argv) != 2:
print('Usage: ecpy <filename>')
sys.exit(1)
try:
print('my PID: %d' % os.getpid())
with open(sys.argv[1], 'w') as fp:
try:
fp.write('Hello Stack Overflow!')
except IOError as e:
print('### before close')
print(str(e))
sys.stdout.flush()
except IOError as e:
print('### after close')
print(str(e))
sys.stdout.flush()
print('### after exception block')
sys.stdout.flush()
由于I / O是缓冲的,如果您使用/dev/full
运行此代码,则在fp
块结束时with
关闭之前,它不会失败。这并不奇怪。在Python 2.7.3rc2中(在我的系统上),代码在实际关闭与fp
对应的文件描述符后运行异常处理程序:
write(3, "Hello Stack Overflow!", 21) = -1 ENOSPC (No space left on device)
close(3) = 0
munmap(0x7f9de3f78000, 4096) = 0
write(1, "### after close\n", 16) = 16
write(1, "[Errno 28] No space left on devi"..., 35) = 35
write(1, "### after exception block\n", 26) = 26
但是,在Python 3.2.3(在我的系统上),文件描述符在异常块运行后仍然打开:
write(3, "Hello Stack Overflow!", 21) = -1 ENOSPC (No space left on device)
write(1, "### after close\n", 16) = 16
write(1, "[Errno 28] No space left on devi"..., 35) = 35
write(1, "### after exception block\n", 26) = 26
...
write(3, "Hello Stack Overflow!", 21) = -1 ENOSPC (No space left on device)
write(3, "Hello Stack Overflow!", 21) = -1 ENOSPC (No space left on device)
close(3) = 0
解释器尝试多次写入文件并无声地失败。 Python什么时候实际调用close()
?什么在调用它?此行为似乎泄漏了文件描述符。
答案 0 :(得分:2)