brysj22952 avatar

PyH源码解析(1)

brysj22952

Published: 08 Aug 2018 › Updated: 08 Aug 2018

PyH源码解析(1)

前言

PyH是什么,以及它有什么用,在之前的博文中有说明:《Python语言PyH模块生成HTML文档使用说明》。
我为什么要写这篇文章呢?并不是基于崇高的乐于分享的心理,主要还是为我自己服务。我发现已经读懂的别人的代码,包括我自己写得代码,时间一长,就忘记了,再阅读源码,虽不至于像全新的一样,还是要耗费很多的精力。所以,我就想把代码的设计思路写成文档,也许会好一些。
为什么要写单独的文档呢?为什么不用良好的代码注释搞定呢?我发现这很困难,代码是平面的,难以反映立体的、更高层次的设计意图。另外,也很难嵌入直观的图表和示意图。

生成Tag对象

描述源码的设计思路有很多方法,我偏向于实例法。不直接描述设计的结果,而是先描述设计的目标,设计的思路,设计的原因。基于这个考虑,我就从使用者的角度、从外在特性出发,来逐步显现设计的轮廓。
我们先看一个用户的使用场景:

>>> a=div()
>>> print(a)
<div>
</div>

类工厂

很明显,div是一个对象,最简单的设计思路是定义一个div类。可是,Tag对象有很多,它们的行为特征也类似,一个个的定义,既繁琐又重复,所以需要动态向模块中注入Tag类的定义。下面就讲一下主要过程。

#设置Tag列表
tags = ['html', 'body',...]
#获取当前模块对象
thisModule = modules[__name__]
#为模块对象增加Tag属性,其中t表示枚举tags中的tag
#需要注意的是,setattr除了设置属性的值,如果属性不存在,还可以增加一个新属性
setattr(thisModule, t, TagFactory(t))
#这里面有一个重要技巧,下面的函数,返回一个类对象,这个类对象被赋予tag属性的值
#所以,当a=div()时,div就是一个属性,它等于一个类对象,所以,div()表示生成一个div对象,它继承自Tag对象
def TagFactory(name):
    122     class f(Tag):
    123         tagname = name
    #__name__:表示类的名字
    124     f.__name__ = name
    125     return f

打印Tag

一个Tag,形如<div id='abc'>xx<div/>,那么打印的逻辑就很清楚了。形如<{tagname} {属性字符串}> 内容或者子TAG <tagname/>

  • tagname:所以,Tag对象就有一个tagname属性成员,它就是形如div的字符串。
  • renderAttr():这个函数就是显示属性字符串的。
  • 内容或者子Tag以后再讲
  • Tag的结尾,这个比较简单,就不讲了。

这段实现代码,有一些地方我觉得需要重构一下。

  • selfClose():这个函数的作用是判断这个Tag是不是自己Close的,比如<input xxx />。我想修改的地方是函数名,我建议返回bool值的函数都应该使用Isxxx,Ruby语言中可以在函数名后面添加?表示返回bool值,但是python不支持,所以我的习惯是前面加上Is,表示判断。
  • self.IsSelfClose*‘/’:这里使用bool值乘以一个字符,给我造成了困扰,通过查阅,发现True就是1,False就是0,就相当于1或者0乘以一个字符,我觉得这种小技巧不是必要的,会引起混淆。不如改成:'' if(self.IsSelfClose) else '/',其实我觉得这种语法也很怪,为什么不用其他语言常用的三目运算符呢?形如:self.IsSelfClose?'':'/',不是更直观简洁吗?

Leave PyH源码解析(1) to:

Written by

Read more #cn posts


Best Posts From brysj22952

We have not curated any of brysj22952's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.

More Posts From brysj22952