是否正确理解以下两个功能完全相同?无论如何调用它们。
def test():
file = open("testfile.txt", "w")
file.write("Hello World")
def test_2():
with open("testfile.txt", "w") as f:
f.write("Hello World")
因为当不再引用对象时python会调用close方法。
如果没有,那么这句话使我感到困惑:
当文件的引用对象时,Python自动关闭文件 被重新分配给另一个文件。最好使用 close()方法关闭文件。
答案 0 :(得分:11)
不,在第一种情况下,Python垃圾回收器(finalizer)将调用close
方法,在第二种情况下,将立即调用test
方法。如果您循环调用test_2
或RLIMIT_NOFILE
函数数千次,则观察到的行为可能会有所不同。
File descriptors是(至少在Linux上是)宝贵而稀缺的资源(耗尽时,open(2) syscall会失败)。在Linux上,将getrlimit(2)与cat /proc/$$/limits
一起使用来查询process的文件描述符数量限制。一旦文件句柄无用,您应该希望快速调用close(2)系统调用。
您的问题是特定于实现,特定于操作系统和特定于计算机的。您可能需要阅读Operating Systems: Three Easy Pieces来了解有关操作系统的更多信息。
在Linux上,也请在终端中尝试cat /proc/self/limits
或Max open files
命令。您会看到一行以{{1}}开头的行(在我的Debian台式机上,现在是2019年12月,软限制是1024)。参见proc(5)。
答案 1 :(得分:2)
不。第一个将无法正确保存信息。您需要使用file.close()
来确保正确关闭文件并保存数据。
另一方面,with
语句为您处理文件操作。只要程序在相同的缩进级别上继续执行,它就会保持文件打开状态,并且只要它升到更高的级别,它就会自动关闭并保存文件。
更多信息here。
答案 2 :(得分:1)
如果使用test
函数,则在Python垃圾收集器将close
之前,不会调用del f
方法,在这种情况下,它是由文件__del__
的magic方法调用的删除变量。
对于test_2
函数,当代码执行超出close
语句时,将调用with
方法。进一步了解with
语句使用的python上下文管理器。
with foo as f:
do_something()
大约只是以下方面的语法糖:
f = foo.__enter__()
do_something()
f.__exit__()
,如果是文件,__exit__
隐式调用close
答案 3 :(得分:1)
否,未正确理解。 close
方法是通过__exit__
方法调用的,该方法仅在退出with
语句时调用,而不在退出函数时调用。 Se代码示例如下:
class Temp:
def __exit__(self, exc_type, exc_value, tb):
print('exited')
def __enter__(self):
pass
def make_temp():
temp = Temp()
make_temp()
print('temp_make')
with Temp() as temp:
pass
print('temp_with')
女巫输出:
temp_make
退出
temp_with