获取某个属性具有特定值的类实例

时间:2011-11-03 20:14:04

标签: python class

我确信有一个关于我正在寻找的术语,或者如果没有,有一个很好的理由我想要做的事实上是愚蠢的。

但无论如何。我想知道是否有(准)内置方​​法来查找某个属性设置为某个值的类实例。

一个例子:

class Klass(object):
    def __init__(self, value):
        self.value = value
    def square_value(self):
        return self.value * self.value

 >>> a = Klass(1)
 >>> b = Klass(2)
 >>> instance = find_instance([a, b], value=1)
 >>> instance.square_value()
 1
 >>> instance = find_instance([a, b], value=2)
 >>> instance.square_value()
 4

我知道我可以编写一个循环遍历所有Klass实例的函数,并返回具有请求值的函数。另一方面,这个功能感觉好像它应该存在于Python中,如果不存在,那么必定有一个非常好的理由为什么它不存在。换句话说,我在这里尝试做的事情可以用更好的方式完成。

(当然,我不是在寻找一种方法来设定一个值。上面只是我想要寻找的构造的一个例子。)

2 个答案:

答案 0 :(得分:4)

使用过滤器:

filter(lambda obj: obj.value == 1, [a, b])

过滤器将返回符合您指定要求的对象列表。文档:http://docs.python.org/library/functions.html#filter

基本上,filter(fn, list)会对list进行迭代,并对每个项目应用fn。它收集fn返回true的所有项目,然后将其放入列表中,然后返回它们。

注意:过滤器将始终返回列表,即使只有一个匹配的对象。因此,如果您只想返回匹配的第一个实例,则必须执行以下操作:

def find_instance(fn, objs):
    all_matches = filter(fn, objs)
    if len(all_matches) == 0:
        return False # no matches
    else:
        return all_matches[0]

或者,更好的是,

def find_instance(fn, objs):
    all_matches = filter(fn, objs)
    return len(all_matches) > 0 and all_matches[0] # uses the fact that 'and' returns its second argument if its first argument evaluates to True. 

然后,你会像这样调用这个函数:

instance = find_instance(lambda x: x.value == 1, [a, b])

然后instance将为a

答案 1 :(得分:2)

如果您只寻找一个匹配的实例,Ord的答案的更高效版本将是

def find_instance(fn, objs):
    all_matches = (o for o in objs if fn(objs))
    return next(all_matches, None)

instance = find_instance(lambda x: x.value == 1, [a, b])

一旦找到第一个匹配项就会停止搜索(如果您的测试功能很贵或列表很大,则会很好),如果没有任何匹配项,则会None

请注意next函数是Python 2.6中的新功能;在旧版本中,我认为你必须这样做

try:
   return all_matches.next()
except StopIteration:
   return None

当然,如果你只是这样做一次,你可以做一个单行:

instance = next((o for o in [a, b] if o.value == 1), None)

后者的优点是不会进行大量的函数调用,所以可能会稍快一些,尽管差异可能很小。