美文网首页
python字典的key只能是不可变类型?

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

作者: hsiaojun | 来源:发表于2021-04-24 23:23 被阅读0次

    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只能是不可变类型?

          本文链接:https://www.haomeiwen.com/subject/xudrrltx.html