tags:

views:

102

answers:

1

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).

Here's an example from 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)?

+7  A: 

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:

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')
Nadia Alramli
+1 nice usage for a decorator
D.Shawley
Perfect, Nadia-- Thanks!
Ross M Karchner
Though it doesn't handle the "argument is actual data" case, but I supposed Feedparsers implementation of that bit is reasonable (line 2705, if the call to open() fails, treat the input as the data to process)
Ross M Karchner