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

如果你知道只有一个匹配,你可以这样做:

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

我认为你在这里尝试做两件不同的事情。

首先,您想按名称获取特定的球。为此,gnibbler 已经给了你答案。

然后,您想按名称获取球的属性之一。为此,请使用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)

另外,你的class定义是错误的:

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

您可能希望这是类中的__init__方法ball,而不是class定义本身:

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

但是,您可能需要重新考虑您的设计。如果您通过名称动态访问属性比直接访问属性更频繁,通常最好只存储一个dict. 例如:

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]]

或者你甚至可能想继承dictorcollections.MutableMapping或其他什么,所以你可以这样做:

the_value = the_ball[sys.argv[2]]

此外,您可能需要考虑使用dict按名称键入的球,而不是列表:

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

the_ball = dict_of_balls[sys.argv[1]]

如果您已经构建了,则可以很容易地list从中构建:dict

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 回答