After I wrote this function, which returns a list of item titles, I
noticed that most item attributes would be retrieved the same way,
i.e., the function would look exactly the same, except for the single
data.append line inside the for loop.
In CL, I could simply write a macro, then replace the data.append line
depending on which attribute I wanted.
Is there anything similar in Python?
Here's the function:
def item_titles (feed_url):
"""Return a list of the item titles found in this feed url"""
data = []
feed = feedparser.parse(feed_url)
if feed:
if len(feed.version) > 0:
for e in feed.entries:
data.append(e.title.encode('utf-8'))
return data
No, there are no macros. Yet it has - amongst other options, such as
callbacks - decorators, that would allow you to write your code like this:
def items (feed_url):
feed = feedparser.parse(feed_url)
if feed:
if len(feed.version) > 0:
for e in feed.entries:
yield e
titles = []
other_things = []
for item in items(url):
titles.append(item.title.encode('utf-8'))
other_things.append(item.other_thing)
Diez
Yes, use higher-order functions. See below.
>
> Here's the function:
>
> def item_titles (feed_url):
Replace previous line with:
def item_titles(feed_url, attr_getter):
> """Return a list of the item titles found in this feed url"""
> data = []
> feed = feedparser.parse(feed_url)
> if feed:
> if len(feed.version) > 0:
> for e in feed.entries:
> data.append(e.title.encode('utf-8'))
Replace previous line with:
data.append(attr_getter(e))
> return data
Example usage:
def title_getter(entry):
return entry.title.encode('utf-8')
titles = item_titles("some feed url here", title_getter)
As I'm not familiar with feedparser, you might want to move where the
.encode() takes place, but you get the idea.
Cheers,
Chris
--
Follow the path of the Iguana...
http://rebertia.com
Something like this?
def item_attrs (feed_url, attr):
"""Return a list of the item titles found in this feed url"""
data = []
feed = feedparser.parse(feed_url)
if feed:
if len(feed.version) > 0:
for e in feed.entries:
data.append(getattr(e, attr).encode('utf-8'))
return data
You're not making it clear how the data.append... line changes so it's
hard to know exactly.
--
Arnaud
No macros -- need the whole "code as data" paradigm which doesn't exist
in python.
The pythonic way to create the sort of abstraction you're looking for
would be to use the *attr functions and either a map of attribute
identities or inspect the attributes from the objects.
Some UNTESTED code...
def extract_entry(e, attrs=['title', 'datetime', 'article']):
out = []
for attr in attrs:
assert hasattr(e, attr)
out.append(getattr(e, attr))
return out
Using the inspect module would give an even more generic function, but
with more complex code of course.
Then your code would look more like:
def items(feed_url):
feed = feedparser.feed(feed_url)
if feed and len(feed) > 0:
return [extract_entry(entry) for entry in feed.entries]
Of course, I'm making liberal assumptions about what you're looking for
in your ouput here... but it's just an example, not a full
solution. YMMV. Hope it helps. :)
Thanks; this is exactly what I was looking for.