我正在学习一个教程,并且我在下面编写了代码。我不明白的一件事是,为什么我们不在post对象上调用html方法?其次,Post函数从哪里获取路径参数?
from flask import Flask,render_template
import markdown
from werkzeug.utils import cached_property
import os
FILE_EXTENSION = '.md'
app = Flask(__name__)
class Post(object):
def __init__(self,path):
self.path = path
@cached_property
def html(self):
with open(self.path,'r') as file_input:
content = file_input.read().strip()
return markdown.markdown(content)
@app.route('/')
def index():
return 'Hello World'
@app.route('/blog/<path:path>')
def post(path):
path = os.path.join('posts', path + FILE_EXTENSION)
post = Post(path)
return render_template('post.html',post = post)
if __name__ == '__main__':
app.run(debug=True)
答案 0 :(得分:2)
首先,您使用装饰器标记了post()
函数,告诉Flask要路由到该函数的URL:
@app.route('/blog/<path:path>')
def post(path):
请参阅那里的<path:path>
元素?现在,任何超过网址/blog/
部分的内容都会被作为post()
参数传递给path
,因此,如果您访问http://localhost:8000/blog/foo/bar/baz
,那么Flask会将路径移过{ {1}}并致电/blog/
。 post('foo/bar/baz')
来自哪里。
模板负责生成HTML:
path
这将在模板目录中查找文件return render_template('post.html',post = post)
,并将其作为Jinja2模板页面执行。它可以访问post.html
变量,因为你传入了它。它是完成所有HTML工作的模板;该模板包含一行post
,以包含{{ post.html|safe }}
方法的结果。
您的Post.html()
类使用缓存属性作为Post
方法。这意味着两件事:
它是property,这意味着您可以间接通过将其视为属性来调用该方法。 .html()
会在post.html
对象上查找属性,Python会注意到它是descriptor object并在其上调用特殊__get__
method,然后调用{{1}方法。
Werkzeug @cached_property
decorator 缓存实例上的结果。它利用了类属性和实例属性之间的区别。
首次查找时,在实例上找不到post
,因此Python转向Post.html
类。它在那里找到post.html
描述符,调用它,Post
描述符调用实际的html
方法。然后将该调用的结果存储为实例属性。在此之后,每次查找 cached_property
时,实例本身都有一个可以使用的属性。