国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

web.py源碼分析: 模板(1)

Rocko / 3155人閱讀

摘要:模板函數(shù)到底長(zhǎng)什么樣下面我們就可以來(lái)看看模板函數(shù)到底長(zhǎng)什么樣了。當(dāng)然,首先得創(chuàng)建一個(gè)模板文件??偨Y(jié)通過(guò)打印中間結(jié)果和分析代碼,我們已經(jīng)大概知道了的模板是如何轉(zhuǎn)化成內(nèi)容的。下一篇文章會(huì)闡述模板的各種語(yǔ)法所對(duì)應(yīng)的動(dòng)態(tài)函數(shù)內(nèi)容。

web.py模板的實(shí)現(xiàn)原理

web.py的模板實(shí)現(xiàn)利用了Python的可執(zhí)行對(duì)象的動(dòng)態(tài)特性:根據(jù)模板內(nèi)容和渲染函數(shù)的參數(shù)創(chuàng)建一個(gè)函數(shù),該函數(shù)執(zhí)行的時(shí)候會(huì)返回一個(gè)TemplateResult類(lèi)實(shí)例,該實(shí)例的字符串化就是模板對(duì)應(yīng)的HTML內(nèi)容。

實(shí)驗(yàn)環(huán)境搭建

為了說(shuō)明web.py的模板是如何實(shí)現(xiàn)的,我們需要在web.py的模板實(shí)現(xiàn)代碼中加入一些打印語(yǔ)句來(lái)顯示中間結(jié)果。Python的virtualenv工具很好的實(shí)現(xiàn)了這個(gè)需求。另外,我還使用了iPython,不過(guò)Python標(biāo)準(zhǔn)命令行也是可以的。環(huán)境搭建的步驟簡(jiǎn)述如下:

創(chuàng)建virtualenv環(huán)境:virtualenv env

激活virtualenv環(huán)境:cd env以及source bin/activate

安裝web.py:pip install web.py

這個(gè)web.py庫(kù)會(huì)被安裝在virtualenv環(huán)境的目錄下:

(env)? ~/programming/python/env/lib/python2.7/site-packages/web  $ pwd
/home/diabloneo/programming/python/env/lib/python2.7/site-packages/web

下面就可以修改這個(gè)web.py的代碼來(lái)看看模板到底是如何實(shí)現(xiàn)的。

實(shí)驗(yàn)代碼修改

我們要修改的代碼位于web/template.py文件內(nèi),找到Template類(lèi)的compile_template函數(shù)(在template.py文件的第900行),加入一行打印語(yǔ)句:

def compile_template(self, template_string, filename):
    code = Template.generate_code(template_string, filename, parser=self.create_parser())

    def get_source_line(filename, lineno):
        try:
            lines = open(filename).read().splitlines()
            return lines[lineno]
        except:
            return None

    print code  # 這行就是我們?cè)黾拥恼{(diào)試語(yǔ)句,可以打印出前面提到的動(dòng)態(tài)生成的函數(shù)。
    try:
        # compile the code first to report the errors, if any, with the filename
        compiled_code = compile(code, filename, "exec")
    except SyntaxError, e:
    ...
    
模板函數(shù)到底長(zhǎng)什么樣?

下面我們就可以來(lái)看看模板函數(shù)到底長(zhǎng)什么樣了。當(dāng)然,首先得創(chuàng)建一個(gè)模板文件。在我們的實(shí)驗(yàn)環(huán)境中進(jìn)行如下操作:

(env)? ~/programming/python/env  $ ls
bin  include  lib  local
(env)? ~/programming/python/env  $ mkdir app
(env)? ~/programming/python/env  $ ls
app bin  include  lib  local
(env)? ~/programming/python/env  $ cd app
(env)? ~/programming/python/env/app  $ mkdir templates

現(xiàn)在,在templates目錄下創(chuàng)建一個(gè)最簡(jiǎn)單的模板,文件名為hello.html,內(nèi)容如下:

hello, world

下面來(lái)看看根據(jù)這個(gè)模板生成的函數(shù)到底長(zhǎng)什么樣子,在實(shí)驗(yàn)環(huán)境下啟動(dòng)ipython或者python,進(jìn)入到app目錄:

(env)? ~/programming/python/env/app  $ ipython
WARNING: Attempting to work in a virtualenv. If you encounter problems, please install IPython inside the virtualenv.
Python 2.7.8 (default, Oct 20 2014, 15:05:19)
Type "copyright", "credits" or "license" for more information.

IPython 1.0.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython"s features.
%quickref -> Quick reference.
help      -> Python"s own help system.
object?   -> Details about "object", use "object??" for extra details.

In [1]:

執(zhí)行如下代碼就可以看到模板函數(shù)的內(nèi)容:

In [3]: hello = web.template.frender("templates/hello.html")
# coding: utf-8
def __template__():
    __lineoffset__ = -5
    loop = ForLoop()
    self = TemplateResult(); extend_ = self.extend
    extend_([u"hello, world
"])

    return self

In [4]:

上面的函數(shù)__template__()就是我們?cè)黾拥絯eb.py庫(kù)中的那行print code所打印出來(lái)的。從這個(gè)函數(shù)的定義,我們可以看出:

函數(shù)內(nèi)使用了一些預(yù)定義的對(duì)象:ForLoop,TemplateResult等。

函數(shù)的結(jié)果是返回一個(gè)TemplateResult實(shí)例。

那么,現(xiàn)在問(wèn)題來(lái)了:

這個(gè)函數(shù)是如何生成的?

使用的這些預(yù)定義名稱(chēng)從哪里來(lái)的?

TemplateResult實(shí)例的字符串表示如何變成HTML文本的?

本文先來(lái)說(shuō)明TemplateResult實(shí)例是如何產(chǎn)生HTML文本這個(gè)問(wèn)題。

TemplateResult

TemplateResult類(lèi)的定義也在web/template.py文件中,繼承的類(lèi)和實(shí)現(xiàn)的方法如下:

class TemplateResult(object, DictMixin):
   __delattr__ : function
   __delitem__ : function
   __getattr__ : function
   __getitem__ : function
   __init__ : function
   __repr__ : function
   __setattr__ : function
   __setitem__ : function
   __str__ : function
   __unicode__ : function
   _prepare_body : function
   keys : function

其中DictMixin是一個(gè)實(shí)現(xiàn)了大部分字典操作的類(lèi),繼承該類(lèi)的子類(lèi)(也就是這里的TemplateResult)需要實(shí)現(xiàn):__getitem__(), __setitem__(), __delitem__()和keys()方法,以便對(duì)象可以模擬完整的字典操作。需要說(shuō)明的是:DictMixin類(lèi)已經(jīng)過(guò)時(shí)了,現(xiàn)在應(yīng)該使用collections.MutableMapping類(lèi)(該類(lèi)的實(shí)現(xiàn)利用了abc庫(kù)--抽象類(lèi))。

先來(lái)看__init__()函數(shù),

def __init__(self, *a, **kw):
    self.__dict__["_d"] = dict(*a, **kw)
    self._d.setdefault("__body__", u"")

    self.__dict__["_parts"] = []
    self.__dict__["extend"] = self._parts.extend

從初始化函數(shù)可以看出,TemplateResult大部分屬性都存儲(chǔ)在_d這個(gè)字典中,該字典至少包含一個(gè)元素body。所以,外部代碼對(duì)TemplateResult的對(duì)象屬性進(jìn)行增刪改查操作時(shí),實(shí)際上都是在操作內(nèi)部的_d這個(gè)字典。初始化函數(shù)中定義的另外兩個(gè)屬性是:_parts,一個(gè)序列;extend,指向_parts序列的extend()方法,也就是說(shuō)調(diào)用TemplateResult實(shí)例的extend方法實(shí)際上是調(diào)用實(shí)例屬性_parts的extend方法。這個(gè)extend方法我們?cè)谇懊娴?strong>__template__()函數(shù)已經(jīng)見(jiàn)到過(guò)了:

def __template__():
    __lineoffset__ = -5
    loop = ForLoop()
    self = TemplateResult(); extend_ = self.extend
    extend_([u"hello, world
"])

    return self
    

這個(gè)函數(shù)定義了extend_ = self.extend,extend_把模板的內(nèi)容添加到了self._parts這個(gè)序列中。

下面來(lái)看一下TemplateResult如何生成HTML內(nèi)容,這個(gè)就要看__str__()方法了:

def _prepare_body(self):
    """Prepare value of __body__ by joining parts.
    """
    if self._parts:
        value = u"".join(self._parts)
        self._parts[:] = []
        body = self._d.get("__body__")
        if body:
            self._d["__body__"] = body + value
        else:
            self._d["__body__"] = value

def __str__(self):
    self._prepare_body()
    return self["__body__"].encode("utf-8")

主要操作是在_prepare_body()函數(shù)里,主要操作是把_parts中的字符串拼接起來(lái),然后再拼接到body的內(nèi)容后面。

看過(guò)TemplateResult的實(shí)現(xiàn)后,我們可以知道,由模板生成的__template__()函數(shù)最終會(huì)把一堆字符串添加到TemplateResult實(shí)例中,然后再通過(guò)實(shí)例生成HTML字符串。

總結(jié)

通過(guò)打印中間結(jié)果和分析代碼,我們已經(jīng)大概知道了web.py的模板是如何轉(zhuǎn)化成HTML內(nèi)容的。下一篇文章會(huì)闡述web.py模板的各種語(yǔ)法所對(duì)應(yīng)的動(dòng)態(tài)函數(shù)內(nèi)容。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/45359.html

相關(guān)文章

  • web.py源碼分析: 模板(2)

    摘要:上一篇文章源碼分析模板說(shuō)明了的模板的大致工作原理。本文重點(diǎn)講述模板支持的語(yǔ)法是如何轉(zhuǎn)換生成函數(shù)的。模板的名稱(chēng)統(tǒng)一是。模板代碼斷行模板內(nèi)容函數(shù)內(nèi)容從結(jié)果來(lái)看,模板中的斷行只是為了不再結(jié)果中插入一個(gè)多余的換行符而已。 上一篇文章web.py源碼分析: 模板(1)說(shuō)明了web.py的模板的大致工作原理。本文重點(diǎn)講述web.py模板支持的語(yǔ)法是如何轉(zhuǎn)換生成__template__函數(shù)的。 we...

    figofuture 評(píng)論0 收藏0
  • web.py源碼分析: 模板(3)

    摘要:前兩篇文章主要說(shuō)明了的模板系統(tǒng)將模板文件處理后得到的結(jié)果函數(shù)。生成函數(shù)的代碼這個(gè)是模板生成過(guò)程中最長(zhǎng)最復(fù)雜的一段,會(huì)應(yīng)用到的分析功能以及動(dòng)態(tài)編譯功能。參數(shù)都是一個(gè),表示還未解析的模板內(nèi)容。 前兩篇文章主要說(shuō)明了web.py的模板系統(tǒng)將模板文件處理后得到的結(jié)果:__template__()函數(shù)。本文主要講述模板文件是如何變成__template__()函數(shù)的。 Render和frende...

    OnlyMyRailgun 評(píng)論0 收藏0
  • 基于Linux環(huán)境的Web.py框架介紹

    摘要:前言在文章基于環(huán)境搭建框架方法介紹中介紹了客戶(hù)端和服務(wù)器的交互過(guò)程,服務(wù)器接收客戶(hù)端的請(qǐng)求后,由應(yīng)用服務(wù)器對(duì)瀏覽器的請(qǐng)求進(jìn)行處理,將生成的響應(yīng)傳遞給服務(wù)器,再由服務(wù)器返回給客戶(hù)端。 前言 在文章《基于Linux環(huán)境搭建Nginx+uWSGI+Python框架方法介紹》中介紹了客戶(hù)端和Web服務(wù)器的交互過(guò)程,Web服務(wù)器接收客戶(hù)端的請(qǐng)求后,由Web應(yīng)用服務(wù)器對(duì)瀏覽器的請(qǐng)求進(jìn)行處理,將生成...

    caikeal 評(píng)論0 收藏0
  • newrelic python agent 源碼分析-1

    摘要:是應(yīng)用性能管理監(jiān)控解決方案提供商。目錄是列出的命令腳本所在目錄。包含文件如下的函數(shù)是命令執(zhí)行的入口。而對(duì)于硬件信息的檢測(cè)則由進(jìn)行。文檔地址源碼仔細(xì)看下去,太復(fù)雜了。下一篇再分析一個(gè)請(qǐng)求到結(jié)束探針工作的完整過(guò)程吧。 Newrelic 是APM(Application Performance Management)(應(yīng)用性能管理/監(jiān)控)解決方案提供商。項(xiàng)目中,通常用它來(lái)追蹤應(yīng)用的性能。最近...

    szysky 評(píng)論0 收藏0
  • web.py源碼分析: application(1)

    摘要:本文主要分析的是庫(kù)的這個(gè)模塊中的代碼。將結(jié)果轉(zhuǎn)換成一個(gè)迭代器。函數(shù)函數(shù)的定義如下位置位置位置該函數(shù)的參數(shù)中就是,是路由映射表則是,是本次請(qǐng)求路徑。位置,如果是其他情況,比如直接指定一個(gè)類(lèi)對(duì)象作為處理對(duì)象。 本文主要分析的是web.py庫(kù)的application.py這個(gè)模塊中的代碼。總的來(lái)說(shuō),這個(gè)模塊主要實(shí)現(xiàn)了WSGI兼容的接口,以便應(yīng)用程序能夠被WSGI應(yīng)用服務(wù)器調(diào)用。WSGI是We...

    edgardeng 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<