1

I'm trying to create a way to apply a prefix to an item which would modify the item's existing stats. For example in the code below I am trying to apply the 'huge' prefix to the 'jar' item. I'd like to make the code reusable so that I could have different prefixes ('fast', 'healthy') that would modify different item stats.

  • Is it possible to hold the name of a class member in a variable?
    • If so, is there any reason I shouldn't?
    • If not, what alternatives are there?
class Prefix(object):
    def __init__(self, word, stat, valu):
        self.word = word
        self.stat = stat
        self.valu = valu


class Item(object):
    def __init__(self, name, size):
        self.name = name
        self.size = size
    def apply_prefix(self, prefix):
        self.prefix.stat += prefix.valu # <-- Here is my issue
        self.name = prefix.word + ' ' + self.name
        # My hope is to make the code reusable for any stat
    def print_stats(self):
        print self.name, self.size


def main():
    jar = Item('jar', 10)
    huge_prefix = Prefix('huge', 'size', 5)
    jar.apply_prefix(huge_prefix)
    jar.print_stats()
2
  • What do you mean by hold the name of a class member? Commented Dec 11, 2013 at 6:15
  • If the item class could have size or speed, I would like the prefix class stat variable to refer to either size or speed. This would allow me to use one line of code instead of a bunch of if statements. Commented Dec 11, 2013 at 6:19

1 Answer 1

1

You're trying to dynamically refer to some attribute. You do that by using getattr. And if you want to set the attribute, well... that's setattr :)

def apply_prefix(self, prefix):
    target_attr = getattr(self,prefix.stat) #dynamically gets attr
    setattr(self,prefix.stat,target_attr+prefix.valu)

As to whether this is the best coding style: it depends. There are some instances that code is made more clear by use of getattr. Since right now you only have two stats, it seems excessive to need this kind of dynamic attribute referencing, since I could easily do:

bogus_prefix = Prefix('huge','bogus',3)

Which is a valid Prefix, but throws an AttributeError when I try to apply it. That's not the most straightforward thing to debug.

However, there are bonuses to the getattr approach: if you add more stats, you don't have to change a bit (haha) of code in Prefix.

Other alternatives? There are always options in Python. :-)

The way I'd do it is to make Prefix just a dict of word:value pairs. Then apply_prefix would loop over the word keys, updating as many values as I wanted in one shot. It's a similarly dynamic approach, but a bit more scalable.

Sign up to request clarification or add additional context in comments.

2 Comments

This dynamically fetches the correct value but now how can I dynamically assign it to self.(prefix stat) so that jar.size will equal 15?
Edit: Looks like I found the answer just as you commented. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.