68

How do I reference this_prize.left or this_prize.right using a variable?

from collections import namedtuple
import random 

Prize = namedtuple("Prize", ["left", "right"]) 
this_prize = Prize("FirstPrize", "SecondPrize")

if random.random() > .5:
    choice = "left"
else:
    choice = "right"

# retrieve the value of "left" or "right" depending on the choice
print("You won", this_prize.choice)

AttributeError: 'Prize' object has no attribute 'choice'
Martin Thoma
  • 124,992
  • 159
  • 614
  • 958
Peter Stewart
  • 2,857
  • 6
  • 28
  • 30
  • 5
    FYI - You can skip the collections import and just use a dictionary to do the same thing: >>> this_prize = {"left": "FirstPrize", "right":"FirstPrize"} >>> this_prize[choice] >'FirstPrize' – Jason Coon Jan 28 '10 at 18:59
  • Related: http://stackoverflow.com/questions/1167398/python-access-class-property-from-string – S.Lott Jan 28 '10 at 19:00

2 Answers2

110

The expression this_prize.choice is telling the interpreter that you want to access an attribute of this_prize with the name "choice". But this attribute does not exist in this_prize.

What you actually want is to return the attribute of this_prize identified by the value of choice. So you just need to change your last line using the getattr() method...

from collections import namedtuple

import random

Prize = namedtuple("Prize", ["left", "right" ])

this_prize = Prize("FirstPrize", "SecondPrize")

if random.random() > .5:
    choice = "left"
else:
    choice = "right"

# retrieve the value of "left" or "right" depending on the choice

print "You won", getattr(this_prize, choice)
iyrin
  • 612
  • 5
  • 14
AJ.
  • 27,586
  • 18
  • 84
  • 94
108
getattr(this_prize, choice)

From http://docs.python.org/library/functions.html#getattr:

getattr(object, name) returns the value of the named attribute of object. name must be a string

user2314737
  • 27,088
  • 20
  • 102
  • 114
S.Lott
  • 384,516
  • 81
  • 508
  • 779
  • 2
    I think this is the generic way to accomplish the task. Since it makes use of the built-in function designed for the purpose, it should really be the preferred answer. (Yes, I realize this is an old question, but it still shows up in Google.) – monotasker Mar 23 '14 at 19:21
  • 1
    And, naturally the counterpart is `setattr`. `setattr(x, 'foobar', 123)` is the same as `x.foobar = 123`. – kotchwane Dec 04 '20 at 21:50