python从对象列表中获取特定属性

时间:2013-02-21 20:55:51

标签: python

我有一个python数组对象

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

然后用户将通过命令行输入名称和属性。例如,用户可以输入“name1”然后“color”或“weirdName”然后“size”...然后我想根据名称找到对象并打印获取颜色对象或大小对象。我可以这样做,还是需要使用开关盒?

由于

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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]]

或者您甚至可能想继承dictcollections.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}

答案 2 :(得分: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]