使用NamedTemporaryFile

时间:2018-04-17 01:26:24

标签: python temporary-files

with NamedTemporaryFile(suffix='.shp').name as tmp_shp:
    df.to_file(tmp_shp)

在上面的代码中,我收到此错误:

AttributeError: __enter__

如何使用with语句使用命名的临时文件?由于tmp_shp只是一条路径,它是否仍在with之外可用?

3 个答案:

答案 0 :(得分:1)

您使用name属性作为上下文管理器。尝试:

with NamedTemporaryFile(suffix='.shp') as tmp_shp:
    df.to_file(tmp_shp)

答案 1 :(得分:1)

您应该使用NamedTemporaryFile本身的语句,而不是name属性。

with NamedTemporaryFile(suffix='.shp') as tmp_file:
    df.to_file(tmp_file)  # As temp_file is a file object, I think to_file should work?

正如官方文档一样,tmp_file将在with之外删除,除非您将delete=False传递给NamedTemporaryFile

这意味着你应该with NamedTemporaryFile(suffix='.shp', delete=False) as tmp_file:

答案 2 :(得分:1)

name属性是一个字符串;尝试在with语句中访问它使其成为托管资源(并且str没有上下文管理的概念)。您需要管理NamedTemporaryFile本身,并根据需要访问name

with NamedTemporaryFile(suffix='.shp') as tmp_shp:
    df.to_file(tmp_shp.name)  # Access .name here, assuming you need a str

如果to_file接受类似文件的对象(我找不到这种方法的文档),则完全避免使用.name(在任一行中)。

更新:因为您在Windows上you can't actually open a file opened by NamedTemporaryFile with delete=True (the default) until the NamedTemporaryFile is closed(这意味着您无法使用写入该文件句柄的任何数据,因为它已被删除,甚至会引入竞争条件如果仅使用它来生成一个唯一的名称;该文件将在此时被删除,因此您实际上只是创建一个新文件,但其他人可能会竞争您以后创建该文件)。我在这里建议的最好是在没有删除支持的情况下使用它来获取一个唯一的名称,包装它以强制自己删除,例如:

tmp_shp = None
try:
    with NamedTemporaryFile(suffix='.shp', delete=False) as tmp_shp:

        df.to_file(tmp_shp.name)  # Access .name here, assuming you need a str

        ... do any other stuff with the file ...
finally:
    if tmp_shp is not None:
        os.remove(tmp_shp.name)
是的,这很难看。这里没有很多好的选择; NamedTemporaryFile从根本上打破了Windows。