python中dict類型的key值要求是不可變類型,通常來說,我們一般采用int或者str類型來作為字典的key,但是在某些場景中,會造成一定的麻煩。
如我們有一個處理http Request的規則類名為Rule,其定義如下,它由一個Request path和其支持的Request methods數組組成:
class Rule(object): def __init__(self, path, methods): assert(isinstance(path, str)) assert(isinstance(methods, list)) self.path = path self.methods = [method.upper() for method in methods]
現在我們想為每一種Rule(非每一個Rule實例)關聯一個對應的Handler對象,使用一個dict來保存對應關系。
r1 = Rule("/index", ["GET"]) r2 = Rule("/index", ["GET"]) d = {r1: handler} print d[r2] # 兩個不同的對象,打印出None
r1和r2雖然是兩個不同的對象實例,但是在業務邏輯上是一致的,因此如果我們想讓兩個在邏輯上一致的對象被認為是同一個key,可以通過一些手段達到這個效果。
為Rule添加兩個方法__hash__和__eq__,其意義可以查看python官方文檔。
class Rule(object): def __init__(self, path, methods): assert(isinstance(path, str)) assert(isinstance(methods, list)) self.path = path self.methods = [method.upper() for method in methods] def __hash__(self): return hash((self.path, str(self.methods))) def __eq__(self, other): return (self.path, self.methods) == (other.path, other.methods)
然后再執行一下上面的測試代碼,發現可以順利取到handler了:
r1 = Rule("/index", ["GET"]) r2 = Rule("/index", ["GET"]) d = {r1: handler} print d[r2] == handler# 打印出True