Canonical / Idiomatic“做我的意思”当传递一个字符串,可以使用文件名,URL或实际数据来处理

时间:2021-08-25 16:40:18

It's not uncommon to see Python libraries that expose a universal "opener" function, that accept as their primary argument a string that could either represent a local filename (which it will open and operate on), a URL(which it will download and operate on), or data(which it will operate on).

看到Python库暴露一个通用的“开启者”函数并不常见,它接受一个字符串,它可以代表一个本地文件名(它将打开并操作),一个URL(它将下载并运行) on)或数据(它将在其上运行)。

Here's an example from Feedparser.

这是Feedparser的一个例子。

My question is: is there a standard "right" way to do that? Or, A module that implements that bit of functionality (maybe as a decorator)?

我的问题是:有没有标准的“正确”方法呢?或者,一个实现该功能的模块(可能作为装饰器)?

1 个解决方案

#1


Ultimately, any module implementing this behaviour is going to parse the string. And act according to the result. In feedparser for example they are parsing the url:

最终,任何实现此行为的模块都将解析字符串。并根据结果采取行动。例如,在feedparser中,他们正在解析url:

if urlparse.urlparse(url_file_stream_or_string)[0] in ('http', 'https', 'ftp'):
    # do something with the url
else:
    # This is a file path
    return open(url_file_stream_or_string)

Here is a nice decorator that will do this for you:

这是一个很好的装饰,将为您做到这一点:

import urlparse, urllib

def opener(fun):
    def wrapper(url):
        if urlparse.urlparse(url)[0] in ('http', 'https', 'ftp'):
            return fun(urllib.urlopen(url))
        return fun(open(url))
    return wrapper

@opener
def read(stream):
   return stream.read()

read('myfile')
read('http://www.wikipedia.org')

#1


Ultimately, any module implementing this behaviour is going to parse the string. And act according to the result. In feedparser for example they are parsing the url:

最终,任何实现此行为的模块都将解析字符串。并根据结果采取行动。例如,在feedparser中,他们正在解析url:

if urlparse.urlparse(url_file_stream_or_string)[0] in ('http', 'https', 'ftp'):
    # do something with the url
else:
    # This is a file path
    return open(url_file_stream_or_string)

Here is a nice decorator that will do this for you:

这是一个很好的装饰,将为您做到这一点:

import urlparse, urllib

def opener(fun):
    def wrapper(url):
        if urlparse.urlparse(url)[0] in ('http', 'https', 'ftp'):
            return fun(urllib.urlopen(url))
        return fun(open(url))
    return wrapper

@opener
def read(stream):
   return stream.read()

read('myfile')
read('http://www.wikipedia.org')