前引
在了解flask上下文管理机制之前,先来一波必知必会的知识点。
面向对象双下方法
首先,先来聊一聊面向对象中的一些特殊的双下划线方法,比如__call__、__getattr__系列、__getitem__系列。
__call__
这个方法相信大家并不陌生,在单例模式中,我们可能用到过,除此之外,还想就没有在什么特殊场景中用到了。我们往往忽视了它一个很特殊的用法:对象object+()或者类Foo()+()这种很特殊的用法。在Flask上下文管理中,入口就是使用了这种方式。
__getitem__系列
使用这个系列的方法时,我们最大的印象就是调用对象的属性可以像字典取值一样使用中括号([])。使用中括号对对象中的属性进行取值、赋值或者删除时,会自动触发对应的__getitem__、__setitem__、__delitem__方法。
class Foo(object): def __init__(self): self.name = "boo" def __getitem__(self, item): print("调用__getitem__了") if item in self.__dict__: return self.__dict__[item] def __setitem__(self, key, value): print("调用__setitem__方法了") self.__dict__[key] = value def __delitem__(self, key): print("调用__delitem__") del self.__dict__[key] foo = Foo() ret = foo["name"] # print(ret) # 输出 调用__getitem__了 boo foo["age"] = 18 # print(foo["age"]) # 输出 调用__setitem__方法了 调用__getitem__了 18 del foo["age"] # 输出 调用__delitem__
__getattr__系列
使用对象取值、赋值或者删除时,会默认的调用对应的__getattr__、__setattr__、__delattr__方法。
对象取值时,取值的顺序为:先从__getattribute__中找,第二步从对象的属性中找,第三步从当前类中找,第四步从父类中找,第五步从__getattr__中找,如果没有,直接抛出异常。
class Foo(object): def __init__(self): self.name = "boo" def __getattr__(self, item): print("调用__getattr__了") def __setattr__(self, key, value): print("调用__setattr__方法了") def __delattr__(self, item): print("调用__delattr__") foo = Foo() ret = foo.xxx # 输出 调用__getattr__了 foo.age = 18 # 调用__setattr__方法了 del foo.age # 输出 调用__delattr__