使用命名临时文件

Using NamedTemporaryFile

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

在上面的代码中,我得到了这个错误:

AttributeError: __enter__

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

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

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

您应该对 NamedTemporaryFile 本身使用 with 语句,而不是它的 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:

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 上根本被打破了。