python字典的key只能是不可变类型?

2021年4月份去富途面试问道的问题,现在记录一下
python中dict类型的key值要求是不可变类型,通常来说,我们一般采用int或者str类型来作为字典的key,但是可不可以用可变类型作为dict的key呢?
当时面试官给出了下面这道题,代码大致如下:

class Dog():

    def __init__(self, name, color):
        self._n = name
        self._c = color
   
# 初始化三个对象 
dog_1 = Dog(name='mike', color='red')
dog_2 = Dog(name='tom', color='blue')
dog_3 = Dog(name='tom', color='blue')

# 字典,并用初始化的对象作为key,设置value
house = {}
house[dog_1] = 1
house[dog_2] = 2

# 打印出三个对象的哈希值,发现dog_2  dog_3是相等的
print(hash(dog_1))  # 2766680834235181893
print(hash(dog_2))  # 9159254995178818247
print(hash(dog_3))  # 9159254995178818247

# 取值
for item in house:
    print(house[item])  # 1 2

要求如下:
print(house[dog_3] == 2) # 当打印house[dog_3] 结果为2

当时这道题目没做出来,回来后查找相关,才发现这道题的考点是python当中的两个魔法方法 ,代码如下

# 为Rule添加两个方法__hash__和__eq__,其意义可以查看python官方文档。

class Dog():

    def __init__(self, name, color):
        self._n = name
        self._c = color
    
    # 关键代码,富途面试
    def __hash__(self):
        return hash(self._n + self._c)

    # 关键代码,富途面试
    def __eq__(self, other):
        return (self._n, self._c) == (other._n, other._c)

其实这道题的考点是从flask框架中路由装饰器中@app.route()中延伸出来的,有兴趣的朋友可以去看看【flask路由映射map表】相关资料,也可以自己尝试去看看flask路由相关源码

route装饰器

在Flask应用中,我们一般通过decorator装饰view函数,来注册一个路由,表示url和处理函数的对应关系,例如:

@app.route('/')
def index():
      return 'Hello World'

route装饰器定义如下, 其本质是调用了Flask对象的add_url_rule函数:

def route(self, rule, **options):
    def decorator(f):
        endpoint = options.pop('endpoint', None)
        self.add_url_rule(rule, endpoint, f, **options)
        return f
    return decorator    

add_url_rule函数签名为def add_url_rule(self, rule, endpoint=None, view_func=None, **options),其主要做了以下4件事情:

1,endpoint默认取view函数名称
2,提供默认的 http方法(HEAD, OPTION)
3,创建url_rule_class对象(url_rule_class默认为werkzeug.routing.Route类),并添加到url_map中(werkzeug.routing.Map对象)
4,将endpoint和view_func保存到view_functions字典中

最后抛出一个问题:flask路由中装饰器什么时候执行呢?

你可能感兴趣的:(python字典的key只能是不可变类型?)