一个python字典实现,支持属性、类变量和继承以满足复杂的模板化需求。

propdict的Python项目详细描述


一个python字典实现,支持属性、类变量和继承以满足复杂的模板化需求。

travis_status测试了Python2.6、2.7和3.3

动机

重写类的特定行为很容易:创建一个子类(甚至仅仅是一个实例)并实现您感兴趣的方面并完成它。不过,模板就不是这样了。如果要更改其中的一部分,则需要重写整个模板,实质上是派生模板作者的工作。

propdict通过允许模板作者将逻辑和行为放入到模板而不是模板本身的数据中来对此进行反驳。

模板的使用者可以简单地对基于propdict的数据进行子类化,覆盖特定方面并保持模板不变。

基本功能

propdict实例的行为几乎与常规字典完全相同,只是您可以使用dict表示法或属性表示法访问值:

>>> server_foo.ip_addr
'10.0.0.1'
>>> server_foo['ip_addr']
'10.0.0.1'
>>> print server_foo['ifconfig']
ifconfig_em0="inet 10.0.0.1 netmask 255.255.255.0"
>>> print server_foo.ifconfig
ifconfig_em0="inet 10.0.0.1 netmask 255.255.255.0"

同样的方法也适用于作业:

>>> server_foo.ip_addr = '192.168.1.1'
>>> print server_foo.ip_addr
192.168.1.1
>>> server_foo['ip_addr'] = '127.0.0.1'
>>> print server_foo.ip_addr
127.0.0.1

当然,赋值也适用于更改属性,如您在示例中所见:

>>> server_foo.ifconfig = u'foo mask'
>>> print server_foo.ifconfig
foo mask

不过,值得注意的是,您不能删除属性。但是,您可以删除属性的自定义values,但这只会重新公开它们的原始值:

>>> del server_foo['ifconfig']
>>> print server_foo.ifconfig
ifconfig_em0="inet 127.0.0.1 netmask 255.255.255.0"
>>> del server_foo['ifconfig']
Traceback (most recent call last):
...
KeyError: 'ifconfig'

示例

假设你是set of templates for configuring *NIX style systems的作者。当然,这些模板中的许多都将使用相同的值,例如正在配置的计算机的IP地址。现在,一些其他值反过来也取决于IP地址的值。假设一个这样的文件有一行使用网络掩码配置网络接口,那么您最终得到一个包含以下代码片段的模板:

>>> template = '''ifconfig_%(iface)s="inet %(ip_addr)s netmask %(netmask)s"'''

给定一个包含必要数据的字典,其计算结果如下:

>>> print template % dict(ip_addr='192.168.1.1', iface='em0', netmask='255.255.255.0')
ifconfig_em0="inet 192.168.1.1 netmask 255.255.255.0"

这在大多数情况下都可以工作,但是如果您部署的特定主机位于nat之后,并且需要完全不同的配置,而不遵循上述格式,那会怎么样?现在,您需要创建模板的自定义版本(与上面的基本示例不同,它可以是非平凡的长度和复杂性),只是在一行中不同,或者模板的作者需要工作(另一个)不会影响99%的用户的特殊编辑。

第三种解决方案是尽可能简单地保留(这一行)模板:

>>> template = "%(ifconfig)s"

把逻辑编入字典。喜欢这样:

>>> from propdict import propdict
>>> class Host(propdict):
...     ip_addr = None
...     iface = 'em0'
...     netmask = '255.255.255.0'
...     @property
...     def ifconfig(self):
...         return '''ifconfig_%(iface)s="inet %(ip_addr)s netmask %(netmask)s"''' % self
>>> server_foo = Host(ip_addr='10.0.0.1')
>>> print template % server_foo
ifconfig_em0="inet 10.0.0.1 netmask 255.255.255.0"

到目前为止,我们得到了和上面一样的结果。但让我们考虑另一个服务器:

>>> server_bar = Host(ip_addr='10.0.0.2', ifconfig='ifconfig_em1="inet 10.0.0.2 netmask 255.255.0.0"')
>>> print template % server_bar
ifconfig_em1="inet 10.0.0.2 netmask 255.255.0.0"

请注意,ifconfig的新定义如何包含接口的新值(可能此主机有两个内置值),但仍引用ip_addr。在这种情况下,最好不要简单地提供一个新的静态值,而是更好地实现该属性:

>>> class HostBar(Host):
...     iface_2 = 'em1'
...     @property
...     def ifconfig(self):
...         return '''ifconfig_%(iface_2)s="inet %(ip_addr)s netmask %(netmask)s"''' % self
>>> server_bar = HostBar(ip_addr='10.0.0.2', netmask='255.255.0.0')
>>> print template % server_bar
ifconfig_em1="inet 10.0.0.2 netmask 255.255.0.0"

因此,我们可以通过仅更改该值而不接触模板来为ifconfig键提供任意新值,同时仍保留默认行为(它是从接口和IP地址自动为您计算的)。

安装

propdict没有依赖项,可以使用首选工具(如pip、easy_install、buildout和setuptools)简单地作为egg安装。你知道训练。

运行测试

要确保propdict适用于您的安装程序,请运行其测试。您需要从github和py.test结帐,可能是这样:

git clone git@github.com:tomster/propdict
cd propdict
virtualenv .
source bin/activate
pip install pytest-cov

然后,运行所有测试(包括本自述文件):

bin/py.test

如果您做了一些更改并想知道是否违反了保险范围:

bin/py.test --cov propdict --cov-report html --cov-report term test_propdict.py

更改日志

1.1-201310-18

  • 包装修正[fschulze]
  • 在构造函数[fschulze]中支持dict

1.0-2013年10月17日

在生产几个月后,发布了稳定的相同代码。

0.1a1-2013年3月17日

首次公开发行

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

推荐PyPI第三方库


热门话题
java如何使用数据库中的值填充p:selectOneMenu   Java/Junit中的异步单元测试一个非常简单但不成功的例子   在Debian上使用Java连接到MySQL   java测试时如何恢复表中的一条记录/行?   java如何将重点放在jbutton上而不是放在另一个jbutton上?   java我可以从HPROF文件中获取JVM标志吗?   java如何使用自定义比较器在2个集合上保留   java让stringTokenizer将一行文本拆分为预定义变量的最佳方法是什么   Kotlin Android/Java字符串日期时间格式,API21   exchange server EWS Java Api自动发现不工作   netbeans是Java新手,似乎无法修复错误;应为类、接口或枚举。274062   我正在尝试将一些scala代码转换为Java8,以创建新的Lambda和并行集合   流中的分配api(java)   用于串行通信的java Python字节数组