0

私はオブジェクトのPython配列を持っています

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

次に、ユーザーはコマンドラインを介して名前と属性を入力します。たとえば、ユーザーは「name1」、「color」、「weirdName」、「size」の順に入力できます。次に、名前に基づいてオブジェクトを検索し、カラーオブジェクトまたはサイズオブジェクトのいずれかを印刷します。このようにすることはできますか、それともスイッチケースを使用する必要がありますか?

ありがとう

4

3 に答える 3

1

一致するものが 1 つだけあることがわかっている場合は、次のようにできます。

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

複数ある場合は、リストを取得できます。

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

主に名前でボールを検索する場合は、リストではなく辞書に保存する必要があります

名前で属性を取得するにはgetattr

getattr(the_ball, "size")

これを行うのは悪い考えかもしれません

getattr(the_ball, user_input)

user_input が"__class__"、または予期しないものである場合はどうなりますか?

いくつかの可能性しかない場合は、明示することをお勧めします

if user_input == "size":
    val = the_ball.size
elif user_input in ("colour", "color"):
    val = the_ball.color
else:
    #error
于 2013-02-21T21:04:01.777 に答える
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}
于 2013-02-21T21:09:24.887 に答える
0

私の理解が正しければ、属性の値に基づいて、ボールのリストから特定のボールを取得する必要があります。解決策は次のとおりです。

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]
于 2013-02-21T21:17:22.390 に答える