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字典中