烧瓶中的歧义夫妻

时间:2014-05-01 18:03:14

标签: python flask

我正在学习一个教程,并且我在下面编写了代码。我不明白的一件事是,为什么我们不在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)

1 个答案:

答案 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方法。这意味着两件事:

  1. 它是property,这意味着您可以间接通过将其视为属性来调用该方法。 .html()会在post.html对象上查找属性,Python会注意到它是descriptor object并在其上调用特殊__get__ method,然后调用{{1}方法。

  2. Werkzeug @cached_property decorator 缓存实例上的结果。它利用了类属性和实例属性之间的区别。

    首次查找时,在实例上找不到post,因此Python转向Post.html类。它在那里找到post.html描述符,调用它,Post描述符调用实际的html方法。然后将该调用的结果存储为实例属性。在此之后,每次查找 cached_property时,实例本身都有一个可以使用的属性。