首先感谢老板的课程,上午刚看了个这门课,虽然想学但是奈何没钱买啊!然后下午老板就给买了…..幸福来的太突然。
之前用“狗书”学过 Flask, 这次看完课程感觉有些比较新的东西,总结一下,不想看完就忘了。
pipenv
在看这门课程之前一直是用virtualenv来做虚拟环境的管理,感觉还挺好用的。但是课程中七月老师用的是pipenv,相比较而言感觉pipenv确实挺好用的。相比较之下virtualenv总会出一下小问题,比如生成requirements的时候会不怎么特别好用,虽说无关痛痒,但是也挺烦人的。下面列举几个pipenv常用的命令:
- Linux与MacOS下的安装方式
sudo pip install pipenv || brew install pipenv
- 创建or安装虚拟环境
pipenv install [--two || --three]
- 使用可选参数指定python的版本,否则使用默认版本。
- Pipenv会在项目文件夹下自动寻找Pipfile和Pipfile.lock文件,创建一个新的虚拟环境并安装必要的软件包。如果没有找到Pipfile和Pipfile.lock则创建一个新的虚拟环境。
- 安装第三方库
pipenv install module
- 卸载第三方库
pipenv uninstall module
- 进入虚拟环境
pipenv shell
- 打包输出第三方库
pipenv lock
- 退出虚拟环境
exit
add_url_rule
一般情况下我们都使用@route()
这个装饰器来注册路由, 实际上@route()
内部也是调用了add_url_rule
方法来进行路由注册。通常情况下我们都使用装饰器的方式进行路由注册,这种方式也符合我们的书写和阅读习惯。但是有一种情况下必须add_url_rule
方式,即使用类做视图函数时。
@route()
内部实现:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20def route(self, rule, **options):
"""Like :meth:`Flask.route` but for a blueprint. The endpoint for the
:func:`url_for` function is prefixed with the name of the blueprint.
"""
def decorator(f):
endpoint = options.pop("endpoint", f.__name__)
self.add_url_rule(rule, endpoint, f, **options)
return f
return decorator
def add_url_rule(self, rule, endpoint=None, view_func=None, **options):
"""Like :meth:`Flask.add_url_rule` but for a blueprint. The endpoint for
the :func:`url_for` function is prefixed with the name of the blueprint.
"""
if endpoint:
assert '.' not in endpoint, "Blueprint endpoints should not contain dots"
if view_func and hasattr(view_func, '__name__'):
assert '.' not in view_func.__name__, "Blueprint view function name should not contain dots"
self.record(lambda s:
s.add_url_rule(rule, endpoint, view_func, **options))视图函数存储在flask核心对象的
view_functions
中,key
是endpoint
,value
为视图函数。当endpoint
为空时,把视图函数名赋值给endpoint
。规则存放在url_map
中。使用
add_url_rule
方式注册路由:1
2
3
4
5
6
7
8
9
10from flask import Flask
app = Flask(__name__)
# @app.route('/')
def index():
return 'index!'
app.add_url_rule('/', view_func=index)
if __name__ == '__main__':
if __name__ == __main__
有点不想写这个,但是七月老师特地提到了这个就写一下吧。
在python中当一个函数被直接运行时,他的__name__
属性会是__main__
, 所以加上这个会保证一个python程序作为一个包被导入时不会直接运行,否则这个python程序中如果有什么可以直接运行的顶级代码,则会直接运行,而不是等待调用。
flask框架结构
- 一个flask核心对象–
app
- 一个核心对象下包含一个或多个蓝图
- 一个蓝图下包含一个或多个视图函数
上下文
什么是上下文
实现了__enter__
和__exit__
方法的对象。
当我们需要对一个对象添加不属于它的一些属性和方法时,我们便可以设计一个上下文,把新的参数和原有对象放到上下文中,生成一个新的对象。
AppContext
AppContext
是对flask核心对象的封装,
RequestContent
当有一个新的request产生时,flask会生成一个RequestContent,在RequestContent推入_request_ctx_stack
栈之前,flask会检查_app_ctx_stack
的栈顶,如果栈顶为空或者不是当前对象,flask会把AppContent推入_app_ctx_stack
栈中,之后将RequestContent推入_request_ctx_stack
中。
所以说我们在写测试代码的时候会产生RuntimeError: Working outside of application context
错误,这时只需要手动将一个AppContent
推入栈中即可。
with
1 | class MyResource: |
re
的值为__enter__
方法返回的值,with Myresource() as re:
语句会执行__enter__
方法中的内容。- 当
with
语句结束或出现异常时会执行__exit__
方法中的内容。如果__exit__
返回False
则会抛出异常,如果返回True
则不会抛出异常。
配置文件
在七月老师的课程中提出来配置文件可以分成两类,一类是公开的可以上传到GitHub上的,另一类是隐私性的,需要写在gitignore中。
之前我们的做法都是隐私的数据写成环境变量用os来读取,但是我经常碰到os读取不到的问题,所以感觉这种方式也不错,相对在服务器的环境变量中配置到不如在服务器中新开一个私密配置文件。所需要的信息依然写在README中。
线程与进程
一种思想
- 看了七月老师课感觉收获最大的是一种思想。同样是程序,可能实现的功能是一样的,但是感觉七月写的真的有种很优美的感觉,如果自己去写就太粗糙了。
- 代码写了不仅是用来运行的,很大程度上是用来看的,不仅是给自己看,更多时候是给别人看(几个月之后看自己的代码和别人的可能没啥区别,所以说对自己好一点)。所以写一个优雅的程序真的很重要,起码现在我写完的程序我是绝对不想去碰第二次的,太痛苦了。
- 七月的课程中体现了一种拆分的思想,试图函数越简单越好,把逻辑实现放在其他地方。有时候一个功能很简单,可能直接写在试图函数中了,但最好的做法是用一个“函数”去实现。阅读者只需要看你的函数名便知道你要做什么,不要“强迫”阅读者去看你全部的源程序。
- 面向对象的方式编程。课程中面向对象的方式看着很优雅,而我一直在用面向过程的方式,可能对面向对象还不是那么熟悉,以后也要尽量尝试用面向对象的方式。所以说课程中很对面向对象的地方处理的很优雅,但是能力有限就没有总结,之后有机会再写。