user2426206
user2426206

Reputation: 11

Composing functions from class attributes

I'm a Common Lisp programmer learning Python. I'd like to be able to construct a function from parts. For example, if I have a class with attributes, then I can use the dot notation to access the attribute value of a class instance, but apparently I can't build a function to do the same thing. For the code below, I can ask for a.attr1, but bar(a,attr1) doesn't work.

class foo (object):
    def __init__(self, x, y):
        self.attr1 = x
        self.attr2 = y

a = foo(17,23)

print a.attr1

def bar (obj, fun):
    print obj.fun

bar(a, attr1)

NameError: name 'attr1' is not defined

No doubt I'm not thinking in a "pythonic" way, but a slightly more complicated example shows why I want to do this. Suppose I want to return the values in a dict sorted by an attribute:

d = {}
d['a'] = foo(17,23)
d['b'] = foo(13,19)

for v in sorted(d.values(), key = lambda x: x.attr1): print v.attr1

This works fine, but the following function doesn't:

def baz (dict,attr):
    for v in sorted(dict.values(), key = lambda x: x.attr): print v.attr1

baz(d,attr1)

NameError: name 'attr1' is not defined

In Common Lisp I'd pass in attr1 quoted, but there doesn't seem to be a similar functionality in Python. Any suggestions? Thanks!

Upvotes: 1

Views: 85

Answers (1)

Elazar
Elazar

Reputation: 21695

def bar(obj, fun):
    print(getattr(obj, fun))

bar(a, 'attr1')

The problem is that python will not recognize attr1, for a very good reason - there's no such symbol.

Similarly:

def baz(d, attr):
    for v in sorted(d.values(), key = lambda x: getattr(x, attr)):
        print(v.attr1)

>>> d = { 'a':foo(17,23), 'b':foo(13,19) }
>>> baz(d, 'attr1')
13
17

Most of the time, if you are doing such things, what you actually need is a simple dictionary.

Upvotes: 2

Related Questions