通过函数decorator创建轻量级字符串模板。

python-templet的Python项目详细描述


#python模板化使用@templat

这里是一个优雅的轻量级python模板化模块,它支持内联python、快速编译、子模板和子类化,所有这些都在一个简单的decorator模块中实现,由大约125行python实现。


版本4增加了:

*python3支持。
*正确的单元测试,验证python2、python3和pypypy支持。
*只支持unicode字符串(不支持bytestring)。
*删除了空第一行的特殊情况。
*清除了代码的可读性。

templet,只需用@templet注释一个python函数,然后将模板文本放在docstring通常所在的位置。将函数体留空,将创建连接内容的有效代码。

````
from templet import templet

@templet
def mytemplate(animal,body):
"$animal跳过$body。"

print(mytemplate('cow',‘月亮’)
```

这变成了这样的东西:

````
def mytemplate(动物,正文:
out=[]
out.append("the")
out.append(str(animal))
out.append("jumpted over the")
out.append(str(body))
out.append(".")
return'。join(out)
````

所有以$:

`|执行所附代码;使用"out.append(text)"插入text
`$$`;单个`$`
`$`(在行的末尾)的转义是行的延续

模板中`$`的所有普通用法都需要通过将`$$`-加倍来转义,但(如上所述)`$.`,`$(`,`$/`,`$'`,和`$'`.

在实际生成的代码中,行号是精确对齐的,以便在出现代码的模板文件的正确行上报告异常跟踪中的语法错误和运行时错误。

只引入在python中简化长字符串构造所必需的概念;然后鼓励使用普通的python来表示所有其他逻辑。


@templat函数可以对任何返回字符串的函数执行所有操作:它可以递归调用;它可以有变量或关键字参数;它可以是包的成员或类的方法;也可以访问全局导入或调用其他包。因此,尽管构造非常简单,但它将python的所有功能都带到了模板中,@templet的思想扩展得非常好。

除了简单的插值,templet没有发明任何新的数据格式化语法。如果要格式化浮点数,可以编写`${%2.3f`%num}`;如果要转义HTML序列,只需编写`${cgi.escape(消息)}`。虽然不像专门的语法那么简单,但是对于任何python程序员来说都很容易记住、足够简短并且可读。

要循环模板,您需要使用python循环或列表压缩并将子模板作为函数调用:

`````
@template
def doc廑template(table):
"\
<;body>;
<;h1>;${table.name}<;/h1>;
<;table>;
${
对于表中的项:
out.append(self.row廑template(item))
}
<;/table>;
<;/body>;
"
`````


如果您喜欢列表理解,它会稍微简短一些:

`````
@template
def doc模板(表):
"\
<;body>;
<;h1>;${table.name}<;/h1>;
<;table>;
${[表中项的自行模板(项)}
<;/table>;
<;/body>;
"
```

这种设计鼓励简单的模板以直线方式阅读,从长远来看这是一种很好的实践。虽然调用子模板时需要传递状态,但您当然可以使用@templet在"self"上生成方法并传递状态,或者使用对象参数。

但是对于python的可读性,您通常希望缩进一些东西,因此@templet提供了一些工具:

*它标识了统一使用在模板左侧的前导空格的数量,并将它们分隔开。
*它允许您在行尾使用一个`$`作为行的延续。

是:

*在函数中缩进模板文本,就好像它是python代码一样。
*使用python三引号,将开头的引号放在它自己的行上。
*不要缩进html标记-它们太深了,所以请将它们全部放在0列。
*当嵌套变得混乱时,为了可读性,只要在每一行加上一个标记。
*如果布局不需要空格,则可以使用`$`继续。
*在`${{'内缩进代码,然后在其自己的行上放`}(在结束的`}}'被吃掉后的一个新行)。

使用与模板本身使用的前导空格剥离技巧相同,因此您可以像平常一样缩进嵌入的python,并且可以在任何感觉自然的列开始缩进。我通常会将嵌入的python再缩进一个级别。

在需要发出每行都有前导空格的文本的特殊情况下,可以在模板的第一行以要视为第0列的列中的"$"开头,如下:

```
@templet
def indented(x):
"\
$
var val
x$x
"""
`````

一个问题是,开头的"'''''"是应该与def在同一行还是它自己的行上。为了清楚起见,我通常将开头的引号放在它自己的行上,但是为了使列正确对齐,我会立即用python行继续符`"\`.


例如,如果要在一行上实现所有这些,请执行以下操作:



```
<;tr>;<;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;tr>;
```



>
````
@templet
def table-table-u-row(row-u-data)行(row-data):
"
"
>
<;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;lt;col1_class}def">;$
<;a class="${link戋class}"$
$
${{
如果(已注册):out.append('已注册')
}
${cgi.escape(标签文本)}$
<;/td>;$
<;/tr>;
"
"```

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java变量始终存储0值。为什么?   如何使用Java/REST将Azure blob从一个存储容器移动到另一个存储容器?   java将commons DBCP从1.2升级到1.4,我应该害怕吗?   java如何使用分隔符拆分字符串?   java使用数组读取json对象   java在groovy中切片字符串   交换数组java的两个邻域元素   java移动用于确定字符串是否为回文的逻辑   java Android应用程序在一个活动中崩溃   java Sparkjava将webapp文件夹设置为静态资源/模板的文件夹   java复杂条件表达式,用户易用。   java如何仅在表存在时从表中选择值   java I无法将数据从Recyclerview传递到其他活动   java数据结构最佳设计(大数据)   java Android从DatePickerDialogFragment中删除日历视图   java将数据从Firebase获取到片段   数组。sort()在java中运行不正常