Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Python equivalent of Common Lisp Macros?

3 views
Skip to first unread message

dpapathanasiou

unread,
Nov 26, 2008, 2:13:10 PM11/26/08
to
I'm using the feedparser library to extract data from rss feed items.

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

Diez B. Roggisch

unread,
Nov 26, 2008, 2:26:50 PM11/26/08
to
dpapathanasiou schrieb:

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

Chris Rebert

unread,
Nov 26, 2008, 2:30:02 PM11/26/08
to dpapathanasiou, pytho...@python.org
On Wed, Nov 26, 2008 at 11:13 AM, dpapathanasiou
<denis.pap...@gmail.com> wrote:
> I'm using the feedparser library to extract data from rss feed items.
>
> 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?

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

> --
> http://mail.python.org/mailman/listinfo/python-list
>

Arnaud Delobelle

unread,
Nov 26, 2008, 2:44:46 PM11/26/08
to
dpapathanasiou <denis.pap...@gmail.com> writes:

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

J Kenneth King

unread,
Nov 26, 2008, 3:00:50 PM11/26/08
to
dpapathanasiou <denis.pap...@gmail.com> writes:

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

dpapathanasiou

unread,
Nov 26, 2008, 3:26:40 PM11/26/08
to
On Nov 26, 2:30 pm, "Chris Rebert" <c...@rebertia.com> wrote:
> On Wed, Nov 26, 2008 at 11:13 AM, dpapathanasiou
>

Thanks; this is exactly what I was looking for.


0 new messages