# 来作为__storage__的key
return self.__storage__[self.__ident_func__()][name]
except KeyError:
raise AttributeError(name)
def __setattr__(self, name, value):
ident = self.__ident_func__()
storage = self.__storage__
try:
storage[ident][name] = value
except KeyError:
storage[ident] = {name: value}
... ...
# 重载了这两个魔法方法之后
# Local().some_value 不再是它看上去那么简单了:
# 首先我们先调用get_ident方法来获取当前运行的线程/协程ID
# 然后获取这个ID空间下的some_value属性,就像这样:
#
# Local().some_value -> Local()[current_thread_id()].some_value
#
# 设置属性的时候也是这个道理
通过这些分析,相信疑问二也得到了解决,通过使用了当前的线程/协程ID,加上重载一些魔法 方法,Flask实现了让不同工作线程都使用了自己的那一份stack对象。这样保证了request的正常 工作。
说到这里,这篇文章也差不多了。我们可以看到,为了使用者的方便,作为框架和工具的开发者 需要付出很多额外的工作,有时候,使用一些语言上的魔法是无法避免的,Python在这方面也有着 相当不错的支持。
我们所需要做到的就是,学习掌握好Python中那些魔法的部分,使用魔法来让自己的代码更简洁, 使用更方便。
但是要记住,魔法虽然炫,千万不要滥用哦。










