5

How do I pass the name of an object's attribute to a function? For example, I tried:

def foo(object, attribute):
    output = str(object.attribute)
    print(output)

class Fruit:
    def __init__(self, color):
        self.color = color

apple = Fruit("red")
foo(apple, color)

but the above doesn't work because Python thinks that, in foo(apple, color), the color refers to an unitialized variable.

user46242
  • 423
  • 2
  • 4
  • 6

2 Answers2

14

You have two problems:

  1. If you try to call foo(apple, color), you get a NameError because color isn't defined in the scope from which you're calling foo; and
  2. If you try to call foo(apple, 'color') you get an AttributeError because Fruit.attribute doesn't exist - you are not, at that point, actually using the attribute argument to foo.

I think what you want to do is access an attribute from a string of the attribute's name, for which you can use getattr:

>>> def foo(obj, attr):
    output = str(getattr(obj, attr))
    print(output)


>>> foo(apple, 'color')
red

Note that you shouldn't use object as a variable name, as it shadows the built-in type.


As a demonstration of point #2:

>>> class Test:
    pass

>>> def demo(obj, attr):
    print(attr)
    print(obj.attr)


>>> t = Test()
>>> t.attr = "foo"
>>> t.bar = "baz"
>>> demo(t, "bar")
bar # the value of the argument 'attr'
foo # the value of the 'Test' instance's 'attr' attribute

Note that neither value is "baz".

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
5

Use getattr:

>>> print getattr.__doc__
getattr(object, name[, default]) -> value

Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
When a default argument is given, it is returned when the attribute doesn't
exist; without it, an exception is raised in that case.

In your case define foo like this and pass the attribute as a string:

def foo(object, attribute):
    print(getattr(object, attribute))
.
.
.
foo(apple, 'color')
mhawke
  • 84,695
  • 9
  • 117
  • 138