用python写网络数据传输_用40行代码写python网页模版渲染引擎

204a18c0fd737c30b86611fa12a3b765.png

引子

罗布大神最近准备用python做网站,发现python在做网站方面还是比较原始的(相对于世界上最好的计算机语言),没有session,出错显示不完善也就算了,web开发框架也是少啊(还是跟最好的语言比 不是一个数量级)。最最重要的就是 在web框架上开发网站,学习难度陡峭,这样小白们怎么吃得消,完全打乱了python简单易学的规律,所以罗布大神决定自己开发一套简单易学的web开发模式/框架,让小白们学python web编程也如鱼得水,把精力花在解决问题上,而不是学习什么狗屁框架上,我们知道框架的寿命只有三年左右,完全不值得我们把学习精力投资在框架上。

正文

首先我们知道,python做web页面,肯定要把页面/模版和业务逻辑分离,不能把业务代码和html混在一起,就像下面一样

#!/usr/bin/python
# -*- coding: UTF-8 -*-

print "Content-type:text/html"
print                               # 空行,告诉服务器结束头部
print '<html>'
print '<head>'
print '<meta charset="utf-8">'
print '<title>Hello World - 我的第一个 CGI 程序!</title>'
print '</head>'
print '<body>'
print '<h2>Hello World! 我是来自菜鸟教程的第一CGI程序</h2>'
print '</body>'
print '</html>'

看着就觉得很丑陋是不是,这也就讲解下原理而已,真要实际做网页,估计要累死半头牛,绝对不能实战的。俗话说,上帝的归上帝,凯撒的归凯撒,所以我们要把模版/html和业务逻辑/python分离开来,这样势必需要一套模版引擎,能把数据嵌套/替换到模版上去。 在这里罗布大神第一个想到的就是有木有现成的模版引擎可以用,我找呀找,dingo,flask我去太复杂了,有些人觉得容易,你觉得容易你去用呀,话说你给这些框架添加过一行代码么?这些框架作者是你大爷?你咋这么向着他们,说话要客观呀。反正我觉得是太难了。后来找到一个mustache的python版本,pystache。mustache是一个非常舒服的客户端/js模版引擎,我以前用起来很爽的,建议做前端的同学们可以了解下,但是在python下,各种出错,我要疯了,麻烦作者稍微用点心吧,遂放弃,算了算了,自己撸起袖子来写个模版引擎,话说我也是自称大神的人。国内自己写模版引擎或者自己写一门语言解析器的人不多吧,我弱弱的问一下。

开干

说干就干,首先想到的就是python自带的字符串format函数,在这里给大家看下例子,支持字典、列表、对象各种类型,有点接近我们的需求。大家先看看例子 ··· python2.6 开始,新增了一种格式化字符串的函数 str.format(),它增强了字符串格式化的功能。基本语法是通过 {} 和 : 来代替以前的 % 。format 函数可以接受不限个参数,位置可以不按顺序。

>>>"{} {}".format("hello", "world")    # 不设置指定位置,按默认顺序
'hello world'

>>> "{0} {1}".format("hello", "world")  # 设置指定位置
'hello world'

>>> "{1} {0} {1}".format("hello", "world")  # 设置指定位置
'world hello world'

#!/usr/bin/python
# -*- coding: UTF-8 -*-

print("网站名:{name}, 地址 {url}".format(name="菜鸟教程", url="www.runoob.com"))

# 通过字典设置参数
site = {"name": "菜鸟教程", "url": "www.runoob.com"}
print("网站名:{name}, 地址 {url}".format(**site))

# 通过列表索引设置参数
my_list = ['菜鸟教程', 'www.runoob.com']
print("网站名:{0[0]}, 地址 {0[1]}".format(my_list))  # "0" 是必须的

怎么样?看了这几个列子,看的我热血冲动,差点就扑上去,已经很接近模版渲染引擎了 那么我们来写模版吧:模版1 mb.html长这样,是不是很清爽呀

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
    <h1>我的第一个标题</h1>
    <p>网站名:{name}, 地址 {url}</p>
</body>
</html>

程序怎么写呢?

```

#!/usr/bin/python
# -*- coding: UTF-8 -*-
#引入操作系统库
import os,sys
#输出页面文件头部
print ("Content-type:text/htmlnn")
#定义要传给模版的数据
site = {"name": "菜鸟教程", "url": "www.runoob.com"}
#打开模版文件并读取内容
file="mb.html"
if os.path.exists(file) :
        f=open(file)
        str=f.read()            
        f.close()
        #渲染:数据传递给模版
        str=str.format(**site)
    #输出给客户端
        print(str)

好了,亲们,注释写的清清楚楚,我们要用python自带的字符串库format就完成了模版的数据传递/渲染工作,但是不要高兴的太早,format虽然好用,还差点意思,别人家的模版可以支持一般的循环渲染、条件渲染的。比如我要把

list1 = ['physics', 'chemistry', 1997, 2000]这样的一个数组,甚至把一个表格
list2 = [['physics', 'zhangsan', 1998, 2001],
        ['math', '', lisi, 2000]
        ['physics', 'wangwu', 1999, 2003]]渲染

这样的渲染要累死人的吧 渲染list模版要写成,

str="{0[0]}, {0[1]}, {0[2]}, {0[3]}"

然后用 str.format(list1)来渲染,list2的模版已经复杂的我不想写了,并且有时候你根本不知道list2里边到底有几组数据,这时候模版根本没办法写,所以模版要支持一定的逻辑才好,为此,我们需要写一个更牛的format,也就是我标题写的自己写个模版引擎啦,蛤~,原来你说的模版引擎就是format,没错,嗯,不过要深加工下format,format做模版引擎还差点意思的,让我们来定义个函数,扩展format,就叫supformat吧,顾名思义,就是超级format 引入 {for 变量} 内容 {/for} 来执行循环和条件,如果变量为列表 内容会被列表的每个元素重复渲染,如果变量不存在,内容不会被渲染,如果变量不是列表 但存在,变量会被正常渲染,看说明应当一点都不绕口吧,蛤~

#!/usr/bin/python
# -*- coding: UTF-8 -*-
#str:模版字符串  list1:传入的数据,可以是字典、列表、对象
def supformat(str,list1):
        pos=str.find("{for ")

        if pos>=0:
            # print(pos)
            posend=str.find("{/for}",pos)
            if posend<0:
                print("need a {/for}")
                return "";
            prestr=str[0:pos]
            endstr=str[posend+6:]
            keypos=str.find("}",pos)
            listkey=str[pos+5:keypos]
            str=str[keypos+1:posend]
            #print listkey,str
            if list1.has_key(listkey) : #如果变量不存在,内容不会被选择
                mlist=list1[listkey]

                if type(mlist)==list : #如果变量存在 会被渲染
                    c=len(mlist)
                    tmp=""
                    for i in xrange(c):
                        tmp+=supformat(str,mlist[i])#str.format(mlist[i])
                        # print str, mlist[i]

                    str=tmp
                elif mlist: #判断true or false #如果变量不是列表 但存在,变量会被正常渲染
                    str=supformat(str,mlist)#str.format(list['listkey'])
                else: #如果变量为0或者false 不会被渲染
                    str=""
            else: #如果变量不存在,内容不会被渲染
                str=""

            str=supformat(prestr,list1)+str+supformat(endstr,list1) #支持递归渲染
        else:
            # 检查是否字典
            if type(list1)==dict :
                str=str.format(**list1) #字典渲染方式
            else :
                str=str.format(list1) #非字典渲染方式

        return str

这个模版引擎写好了,怎么样,是不是没有想想的那么复杂,老祖宗说的好“天下事有难易乎?为则难者亦易矣”,非常鼓励我们自己的程序员写自己的模版引擎,写自己的框架,发明自己的计算机语言,整天你们叫嚷着别人写的这个框架好,别人发明的那个好,跟你你什么关系,自己写的也就算了,为别人写的东西你们互相奚落,还发明了鄙视链,害不害臊呀? 好了,我们言归正传,看看这个函数怎么用,假设我们把这个函数保存在一个supformat.py的文件里,那么使用的时候,要保证这个文件在当前目录或者sys.path的目录列表里,然后就引入就可以使用了,

#!/usr/bin/python
# -*- coding: UTF-8 -*-
#引入操作系统库
import os,sys
import supformat as sp #引入supformat函数
#输出页面文件头部
print ("Content-type:text/htmlnn")
#定义要传给模版的数据

list2 = [['physics', 'zhangsan', 1998, 2001],
        ['math', '', lisi, 2000]
        ['physics', 'wangwu', 1999, 2003]]

site={"list2":list2}

#打开模版文件并读取内容
file="mb.html"
if os.path.exists(file) :
        f=open(file)
        str=f.read()            
        f.close()
        #渲染:数据传递给模版
        str=supformat(site) # **划重点 模版渲染使用方法**
    #输出给客户端
        print(str)

模版如下

{for list2}
    {} {} {} {}
{/for}

怎么样,模版是不是很清爽,另外要说下 模版里边需要用大括号的地方要用双大括号转义 样式表和js的大括号要写成 {{}}

好了,罗布大神写的web渲染模版引擎就到这里,你也可以直接拿来用,或者对你写自己的程序有所启发,大家如果要学习python也可以来咨询我,可以关注微信: 预约猫 然后输入罗布大神 就会有我的联系方式哦

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值