2009-11-02 81 views
0

希望能够提供对象的集合的搜索界面,通过传递关键字参数列表,像这样使用:** kwargs搜索机制中的对象(蟒蛇)

playerID = players.search(nameFirst='ichiro', nameLast='suzuki') 

,玩家搜索定义如下:

def search(self, **args): 
    ret = [] 
    for playerID, player in self.iteritems(): 
     for key, value in args.iteritems(): 
      if getattr(player, key) == value: 
       ret.append(player.playerID) 

    return ret 

显然上面的代码不起作用。我想借用一些SQL成语,像player.key == value和player.keyN = valueN那样工作,以此类推N个kwargs。

任何想法?谢谢!

回答

1

我想,借用一些SQL成语, 工作等,其中player.key ==价值 和player.keyN =值N,等等 为N个克瓦格斯通过。

所以你目前正在实现一个OR,并且想实现一个AND而不是 - 是吗?

如果是这样,那么all建议在@马克的答案会工作 - 或替代,以及等效尽管以抽象的较低水平:

def search(self, **args): 
    ret = [] 
    for playerID, player in self.iteritems(): 
    for key, value in args.iteritems(): 
     if getattr(player, key) != value: break 
    else: 
     ret.append(player.playerID) 

    return ret 

我不太清楚你为什么循环在iteritems上,然后忽略您获得的密钥(直接附加player.playerID而不是playerID密钥)。

无论如何,另一种高抽象方法,假设你不需要钥匙...:

def search(self, **args): 
    def vals(p): 
    return dict((k, getattr(p, k, None)) for k in args) 
    return [p.playerID for p in self.itervalues() if vals(p) == args] 

这一个不“短路”,但在其他方面等同于马克的。完全等效的,但相当简洁:

def search(self, **args): 
    return [p.playerID for p in self.itervalues() 
      if all(getattr(p, k, None)==args[k] for k in args)] 

如果这些代码段不符合你的需求,你可以澄清到底为什么他们不这样做(!最好有一个例子,三 - ),我敢肯定他们可以调整以满足上述需求。

+0

谢谢你,最后的方法完美地工作。 – Wells 2009-11-02 04:55:31

1

您应该可以将其更改为列表理解,内建函数all,如果参数中的所有元素均为true(或者如果迭代项为空),则返回True。这样的事情应该做的伎俩:

for playerID, player in self.iteritems(): 
    if all(getattr(player, key) == value for key, value in args.iteritems()): 
     ret.append(player.playerID)