2009-11-02 80 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)