1、Flask
- 配置文件
- 路由
- 请求相关&路由
- cookie&session
- 模板jinja2
- 扩展
- 闪现
- 蓝图
- 中间件
2、上下文管理
-----请求上下文:RequestContext
----request 保存用户请求相关信息
----session 保存用户会话相关信息
------应用上下文:AppContext
-----app (current_app) 保存应用对象相关信息
-----g 每个请求周期都会创建的一个用于在请求周期中传递值的一个容器,一般用于传递值。
------- threading.local(哪里还用到过threading.local: DBUtiles,模式一,为每个线程开启一个数据库连接)
实现细节:
--- RequestContext(AppContext)对象通过LocalStack添加到Local中
--- 导入request(session、current_app、g)是LocalProxy对象 ----》通过偏函数 ------》 LocalProxy ----》 Local
--- RequestContext的auto_pop ----》LocalStack.pop -----》 Local中移除
PS: 永远两个Local对象。
------ 多app应用 & 蓝图
------ 为啥用栈?离线脚本测试时,有多个app嵌套时,栈就派上用场了!
------ 面向对象
-----封装
class Foo:
def __init__(self):
self.age = 123
self.name = "12"
class Bar:
def __init__(self):
self.xx = 111
class Base:
def __init__(self):
self.f = Foo()
self.x = Bar()
----某个值+括号 __call__方法
-----函数/方法
------类
-----对象
------特殊的双下划线方法:
__new__ 是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例,是个静态方法。
__init__ 是当实例对象创建完成后被调用的,然后设置对象属性的一些初始值。在__new__之后
__call__ 对象加括号将调用该方法
__str__ print(对象)调用
__setattr__ 设置对象属性.key = value
__getattr__ 获取对象的属性 , 对象.key
__delattr__ 删除对象的属性
__setitem__ 每当属性被赋值的时候都会调用该方法,因此不能再该方法内赋值 self.name = value 会死循环。对象[key]
__getitem__ 当访问不存在的属性时会调用该方法
__delitem__ 当删除属性时调用该方法
__enter__ 紧跟with后面的语句被求值后,返回对象的__enter__()
方法被调用
__exit__ 当with后面的代码块全部被执行完之后,将调用前面返回对象的__exit__()
方法。
__add__ 当python解释器执行到a+b这样的语句时,首先在查找a中有没有__add__操作符,如果a中没有定义,那么就在b中查找并执行__radd__。
PS:在flask的LocalProxy中全部使用过。
----强制调用私有字段:可通过 类名.字段名 ,例如 _LocalProxy__local
在子类中无法调用基类的私有字段
-----源码流程
ps:自定义栈/堆
-------零碎
- LocalProxy类
- 偏函数
- chain
3、信号
4、MetaClass
- MetaClass作用:用来指定当前类由谁来创建的(默认type创建)
- 使用MetaClass:
python3语法:
class Foo(metaclass=type):
pass
python2语法:
class Fool(object):
__metaclass__ = type
pass
- 类继承
class MyType(type):
def __init__(self,*args,**kwargs):
print("init")
super(MyType,self).__init__(*args,**kwargs)
def __call__(self,*args,**kwargs):
print("call本质:调用类的__new__,再调用类的__init__")
return super(MyType,self).__call__(*args,**kwargs)
class Foo(metaclass=MyType):
pass
#运行此程序,将输出: init,因为Foo类在创建时,会调用MyType类的__init__方法
#而运行: obj = Foo()才会调用MyType的__call__方法
class Bar(Foo):
pass
obj = Bar()
#此句将执行两次init,一次call