如何在 Python 中为需要文件名的函数提供 URL

Cat*_*lin 5 python url filenames arguments

我正在寻找一个通用配方,以将 URL 用于需要文件名的函数。我已经困惑了一个,但它有点复杂而且很容易出错。

在本例中,我的函数read_file来自geopandas,但无论如何都会出现同样的问题。

import tempfile, requests
import geopandas as gpd

def as_file(url):
    tfile = tempfile.NamedTemporaryFile()
    tfile.write(requests.get(url).content)
    return tfile

URL = 'https://raw.githubusercontent.com/bowmanmc/ohiorepresents/master/data/congressional.min.json'
tf = as_file(URL)
gpd.read_file(tf.name)
Run Code Online (Sandbox Code Playgroud)

这可行,而且看起来不太糟糕,但我必须进行大量实验才能找到它,因为由于OSError: no such file or directory临时文件的寿命,轻微的变体会引发;但我也不想用永久文件弄乱文件系统。

这失败了:

def as_file(url):
    tfile = tempfile.NamedTemporaryFile()
    tfile.write(requests.get(url).content)
    return tfile.name

gpd.read_file(as_file(URL))
Run Code Online (Sandbox Code Playgroud)

甚至这个:

def as_file(url):
    tfile = tempfile.NamedTemporaryFile()
    tfile.write(requests.get(url).content)
    return tfile

gpd.read_file(as_file(URL).name)
Run Code Online (Sandbox Code Playgroud)

有没有更明显、更容易记住、更安全的方式?

Pet*_*ood 6

您可以使用上下文管理器来管理临时文件的生命周期:

from contextlib import contextmanager

@contextmanager
def as_file(url):
    with tempfile.NamedTemporaryFile() as tfile:
        tfile.write(requests.get(url).content)
        tfile.flush()
        yield tfile.name
Run Code Online (Sandbox Code Playgroud)

注意:它with NamedTemporaryFile() as tfile仅适用于 Python 3。否则,您必须确保它能够为 Python 2 正确清理。

用法:

with as_file(URL) as filename:
    gpd.read_file(filename)
Run Code Online (Sandbox Code Playgroud)