Python 创建声明性迷你语言
2007-03-30 12:31:54 来源:WEB开发网还要注意的是,这些类虽然是用标准 Python 语法创建的,但它们也有不同寻常(且更简练)之处:它们没有方法或实例数据。单独定义类,以便从某框架继承类,而该框架受到单一的类属性限制。例如, <chapter> 是其它标记序列,即 <title> 后面跟着一个或多个 <paragraph> 标记。但是为确保在实例中遵守约束,我们所需做的就是用这种简单的方式来 声明 chapter 类。
编写像 gnosis.xml.validity.Seq 这样的父类程序所涉及的主要“技巧”,就是在初始化期间研究 实例的 .__class__ 属性。类 chapter 自身并不进行初始化,因此调用其父类的 __init__() 方法。但是传递给父类 __init__() 的 self 是 chapter 的实例,而且 self 知道 chapter。为了举例说明这一点,下面列出了部分 gnosis.xml.validity.Seq 实现:
清单 11. 类 gnosis.xml.validity.Seq
class Seq(tuple):
def __init__(self, inittup):
if not hasattr(self.__class__, '_order'):
raise NotImplementedError,
"Child of Abstract Class Seq must specify order"
if not isinstance(self._order, tuple):
raise ValidityError, "Seq must have tuple as order"
self.validate()
self._tag = self.__class__.__name__
一旦应用程序程序员试图创建 chapter 实例,实例化代码就检查是否用所要求的 ._order 类属性声明了 chapter ,并检查该属性是否为所需的元组对象。方法 .validate() 要做进一步的检查,以确保初始化实例所用的对象属于 ._order 中指定的相应类。
何时声明
声明性编程样式在声明约束方面 几乎一直比命令式或过程式样式更直接。当然,并非所有的编程问题都是关于约束的 - 或者说至少这并非总是自然定律。但是如果基于规则的系统(比如语法和推理系统)可以进行声明性描述,那么它们的问题就比较容易处理了。是否符合语法的命令式验证很快就会变成非常复杂难懂的所谓“意大利面条式代码”(spaghetti code),而且很难调试。模式和规则的声明仍然可以更简单。
当然,起码在 Python 中,声明规则的验证和增强总是会归结为过程式检查。但是把这种过程式检查放在进行了良好测试的库代码中比较合适。单独的应用程序应该依靠由像 Spark 或 PLY 或 gnosis.xml.validity 这样的库所提供的更简单的声明性接口。其它像 xmlproc 、 SimpleParse 或 ft.4xslt 这样的库,尽管不是 用 Python进行声明的(Python 当然适用于它们的领域),也能使用声明性样式。
更多精彩
赞助商链接