扫码关注官方订阅号
import pprint pprint.pprint(open(r'c:\text\somefile.txt').readlines())
如上,并没有with啥的,怎么就能自动关闭了呢?
认证0级讲师
File object最终会被垃圾回收机制释放和关闭,但不能保证具体什么时候,根据Python的实现释放时机各有不同。目前CPython使用引用技术做垃圾回收,其他Python(如Jython,Python on JVM)有其他的垃圾回收技术。如果需要保证文件被及时关闭推荐使用with:
import pprint with open(r'/tmp/test.log') as f: pprint.pprint(f.readlines())
用Python 2.7.5(CPython)来验证下面的代码确实在执行time.sleep之前关闭了文件:
# test.py import time import pprint pprint.pprint(open(r'/tmp/test.log').readlines()) time.sleep(20)
使用lsof查看进程在sleep过程中确实没有引用/tmp/test.log文件:
lsof -p pid COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME strace 5088 garry cwd DIR 8,1 4096 9963923 /home/garry/Projects/python strace 5088 garry rtd DIR 8,20 4096 2 / strace 5088 garry txt REG 8,20 434616 823306 /usr/bin/strace strace 5088 garry mem REG 8,20 2093096 793444 /usr/lib64/libc-2.18.so strace 5088 garry mem REG 8,20 154992 786429 /usr/lib64/ld-2.18.so strace 5088 garry 0u CHR 136,1 0t0 4 /dev/pts/1 strace 5088 garry 1u CHR 136,1 0t0 4 /dev/pts/1 strace 5088 garry 2u CHR 136,1 0t0 4 /dev/pts/1
lsof -p pid
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME strace 5088 garry cwd DIR 8,1 4096 9963923 /home/garry/Projects/python strace 5088 garry rtd DIR 8,20 4096 2 / strace 5088 garry txt REG 8,20 434616 823306 /usr/bin/strace strace 5088 garry mem REG 8,20 2093096 793444 /usr/lib64/libc-2.18.so strace 5088 garry mem REG 8,20 154992 786429 /usr/lib64/ld-2.18.so strace 5088 garry 0u CHR 136,1 0t0 4 /dev/pts/1 strace 5088 garry 1u CHR 136,1 0t0 4 /dev/pts/1 strace 5088 garry 2u CHR 136,1 0t0 4 /dev/pts/1
使用strace来观察程序系统调用的过程,可以发现确实在读取数据后立刻关闭了文件:
strace python test.py
// 打开文件,fd为3 open("/tmp/test.log", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=6, ...}) = 0 fstat(3, {st_mode=S_IFREG|0644, st_size=6, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f45a7bc7000 // 读取文件内容 read(3, "lllll\n", 8192) = 6 read(3, "", 4096) = 0 // 关闭文件 close(3) = 0 munmap(0x7f45a7bc7000, 4096) = 0 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f45a7bc7000 // 输出到终端 write(1, "['lllll\\n']\n", 12['lllll\n'] ) = 12 // 执行sleep select(0, NULL, NULL, NULL, {20, 0}) = 0 (Timeout) rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7f45a73d66d0}, {0x7f45a76f5680, [], SA_RESTORER, 0x7f45a73d66d0}, 8) = 0 exit_group(0) = ?
python解释器自动回收的。 open 打开一个临时 file对象,在读取内容以后,引用计数为0。 解释器回收垃圾时销毁file,文件就关闭了。
大概过程就是这样吧~
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
File object最终会被垃圾回收机制释放和关闭,但不能保证具体什么时候,根据Python的实现释放时机各有不同。
目前CPython使用引用技术做垃圾回收,其他Python(如Jython,Python on JVM)有其他的垃圾回收技术。
如果需要保证文件被及时关闭推荐使用with:
用Python 2.7.5(CPython)来验证下面的代码确实在执行time.sleep之前关闭了文件:
使用lsof查看进程在sleep过程中确实没有引用/tmp/test.log文件:
使用strace来观察程序系统调用的过程,可以发现确实在读取数据后立刻关闭了文件:
python解释器自动回收的。
open 打开一个临时 file对象,在读取内容以后,引用计数为0。
解释器回收垃圾时销毁file,文件就关闭了。
大概过程就是这样吧~