pylens-通过镜头的对象序列化
pylens的Python项目详细描述
作者:nick blundell(http://www.nickblundell.org.uk)
这就是问题所在
假设您希望以编程方式更改一个潜在复杂性的一部分 存储在字符串中的结构(例如,可能是unix配置文件),以便 结构的其余部分保持不变,比如注释和 间隔,仍然允许手动维护。
如果我们使用一个典型的解析器解析这样的结构,我们肯定会 提取一个我们可以处理和更改的结构的抽象模型, 但当我们希望将这些更改作为 字符串,因为所有的非语义工件(例如空白、注释, 等)在解析过程中迷失方向。
换言之,我们希望在某些情况下将surgical更改为 绳子,让那些与我们无关的部分不受干扰 改变,因此没有我们践踏可能 对其他合作系统或手册编辑器很重要。
这就是双向编程的概念(参见下面的参考资料 对于更多的背景)可以真正帮助我们。这里我们指定一个所谓的lens, 它是一个解析器,不仅在经典意义上可以解析字符串 变成一个抽象模型(便于操作),但也可以用来编织 我们修改后的结构回到原来的字符串中。
镜头概念通常是经典视图更新问题的概括。 在数据库技术中找到,我们希望修改 一些数据和有变化的数据反映适当。
pylens方法
pylens框架将镜头的概念与python代码紧密地联系在一起,比如 透镜可以简单地用python定义(受 pyparsing)并且可以映射到python和从python映射到python 结构,如列表、听写和类。
这类似于一种特殊的序列化,我们可以从中提取python 从任意字符串结构中构造,可以轻松修改结构,以及 然后通过外科手术将模型放回原来的字符串结构中 它体现了我们的变化。
由于镜头被表示为python类,因此 扩展它们的功能。
示例
假设我们有一个这样的配置文件,假设它有 已读入变量config_string:
# Auto interfaces. auto lo eth0 allow-hotplug eth1 # Define mapping for eth0. mapping eth0 # Mapping script script /usr/local/sbin/map-scheme map HOME eth0-home map WORK eth0-work # eth0 home configuration. iface eth0-home inet static address 192.168.1.1 netmask 255.255.255.0 up flush-mail
我们希望在程序上做一些改变,这样它就变成了 更改用方括号突出显示:
# Auto interfaces. auto lo [wlan0] eth0 allow-hotplug eth1 # Define mapping for eth0. mapping eth0 # Mapping script script [/home/fred/map_script] map HOME eth0-home map WORK eth0-work # eth0 home configuration. iface eth0-home inet static address 192.168.1.1 [dns-nameservers 192.168.1.4 192.168.1.5] netmask 255.255.255.0 up flush-mail [iface wlan0 inet dhcp]
我们使用pylens框架如下:
from pylens import * # Define our python model and a lens for mapping our model to # and from the string structure. class NetworkConfiguration(LensObject) : # Our definition of the lens which maps between the string structure and # this class - this will become clearer in the tutorials. __lens__ = ZeroOrMore(NetworkInterface | auto_lens | HashComment() | BlankLine()) # We can add whatever functions we like for manipulating our class, such # as a constructor. def __init__(self, ...) : ... # Now extract our model's representation from the config string. net_config = get(NetworkConfiguration, CONFIG_STRING) # Then modify the structure using standard python. net_config.auto_interfaces[0].insert(1, "wlan0") net_config.interface_mappings["eth0"].script = "/home/fred/map_script" net_config.interfaces["eth0-home"].dns_nameservers = ["192.168.1.4", "192.168.1.5"] net_config.interfaces["wlan0"] = Interface(address_family="inet", method="dhcp") # Then weave the changes back into the original config string (i.e. change # only what needs to be changed, disturbing as little of the original config # string as possible). CONFIG_STRING = lens.put(net_config)
文档
您可以在这里找到pylens的在线文档: http://packages.python.org/pylens/
为了更详细地了解pylens,您可能还希望查看 源文件,其中包含大量的测试代码,这些代码可以完全工作,但是 尚未记录(例如递归等):
examples/*.py testing/tests.py pylens/*_lenses.py
限制
请注意,这个项目的最初目的是看看镜头的概念 双向编程可以与 像python这样的语言,允许由类和 其他本机类型(例如字符串、浮点数、列表、dict等),但是 是通过妥协实现的,因为目前还没有 镜头行为(如你在下面参考的工具图中所见)。 这就需要对有限状态自动机进行昂贵的分析。简单地说,一个 表现良好的镜头将始终遵循以下规则:
lens.get(lens.put(x)) == x lens.put(lens.get(y)) == y
我感兴趣的是探索如何实现某种确定性 行为进入框架,如果不是完全的歧义检查,但是现在 健全性检查由镜头作者负责,尽管我在 支持增量开发的框架辅助工具镜片的开发和测试, 这会帮助你创造出适合你的东西。
理论
有关派伦的理论和灵感的更多细节,请参见 以下链接。
- 透镜理论:奈特·福斯特等人:http://www.cs.cornell.edu/~jnfoster/
- 功能:http://augeas.net/
- 解析器定义的易用性:pyparsing:http://pyparsing.wikispaces.com/
- 设计:Yean的清洁设计,作者:Markus Brueckner:http://www.slash-me.net/dev/snippets/yeanpypa/documentation.html