0

I have a python array of objects

class ball(self, size, color, name):
  self.size = size
  self.color = color
  self.name = name

then a user will inputs a name and an attribute via the command line. For example a user could input "name1" and then "color" or "weirdName" then "size"... I then want to find the object based on the name and print get either the color object or the size object. Can I do it like this or will I need to use a switch case?

Thanks

1
  • Python has no switch case! Commented Feb 21, 2013 at 21:06

3 Answers 3

1

If you know there is exactly one match, you can do this:

the_ball = next(b for b in list_of_balls if b.name == ???)

If there are multiple then you can get a list:

the_balls = [b for b in list_of_balls if b.name == ???]

If you are primarily looking up balls by their name, you should keep them in a dictionary instead of a list

To retrieve an attribute by name use getattr

getattr(the_ball, "size")

Doing this can be a bad idea

getattr(the_ball, user_input)

what if user_input is "__class__" or something else you didn't expect?

If you only have a few possibilities it's better to be explicit

if user_input == "size":
    val = the_ball.size
elif user_input in ("colour", "color"):
    val = the_ball.color
else:
    #error
Sign up to request clarification or add additional context in comments.

2 Comments

+1. But I think (although I'm not sure) that this only answers the first half of his question; he also wants to get an attribute of the_ball by name. So the full answer is something like your statement, followed by the_attr = getattr(the_ball, user_given_attr_name).
yes, but then i just want to output one of the values, either size or color based on what the user entered
0

I think you're trying to do two different things here.

First, you want to get a particular ball by name. For that, gnibbler already gave you the answer.

Then, you want to get one of the ball's attributes by name. For that, use getattr:

the_ball = next(b for b in list_of_balls if b.name == sys.argv[1])
the_value = getattr(the_ball, sys.argv[2])
print('ball {}.{} == {}'.format(sys.argv[1], sys.argv[2], the_value)

Also, your class definition is wrong:

class ball(self, size, color, name):
  self.size = size
  self.color = color
  self.name = name

You probably meant for this to be the __init__ method inside the ball class, not the class definition itself:

class ball(object):
  def __init__(self, size, color, name):
    self.size = size
    self.color = color
    self.name = name

However, you may want to reconsider your design. If you're accessing attributes dynamically by name more often than you're accessing them directly, it's usually better just to store a dict. For example:

class Ball(object):
    def __init__(self, size, color, name):
        self.name = name
        self.ball_props = {'size': size, 'color': color}

list_of_balls = [Ball(10, 'red', 'Fred'), Ball(20, 'blue', 'Frank')]

the_ball = next(b for b in list_of_balls if b.name == sys.argv[1])
the_value = the_ball.ball_props[sys.argv[2]]

Or you may even want to inherit from dict or collections.MutableMapping or whatever, so you can just do:

the_value = the_ball[sys.argv[2]]

Also, you may want to consider using a dict of balls keyed by name, instead of a list:

dict_of_balls = {'Fred': Ball(10, 'red', 'Fred'), …}
# ...

the_ball = dict_of_balls[sys.argv[1]]

If you've already built the list, you can build the dict from it pretty easily:

dict_of_balls = {ball.name: ball for ball in list_of_balls}

Comments

0

If I understood properly, you need to get a particular ball from a list of balls, based on the value of an attribute. A solution would be:

attribute_value = sys.argv[1]
attribute_name = sys.argv[2]
matching_balls = [ball_item for ball_item in list_balls if \
     getattr(ball_item, attribute_name) == attribute_value]

Comments

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.