跳转到主要内容

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

项目描述

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

travis_status 对Python 2.6、2.7和3.3进行了测试

动机

覆盖类的一个特定行为很简单:创建一个子类(或者甚至只是一个实例),只需实现您感兴趣的部分即可。但是,对于模板来说并非如此。如果您想更改它的一部分,您需要覆盖整个模板,这在本质上就是重新做模板作者的工。

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

然后,模板的消费者可以简单地从基于“propdict”的数据派生子类,覆盖特定的方面,并保持模板不变。

基本功能

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

>>> 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

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

>>> 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'

示例

假设您是一组用于配置*NIX风格系统的模板的作者。当然,这些模板中的许多都会使用相同的值,例如正在配置的机器的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

然后,运行所有测试(包括这个README)

bin/py.test

如果您进行了某些更改并想知道是否破坏了覆盖率

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

变更日志

1.1 - 201310-18

  • 打包修复[fschulze]

  • 在构造函数中支持字典[fschulze]

1.0 - 2013-10-17

在生产环境中经过数月,发布了相同代码的稳定版本。

0.1a1 - 2013-03-17

初始公共发布

项目详情


下载文件

下载适合您平台文件的文件。如果您不确定选择哪个,请了解更多关于安装软件包的信息。

源分布

propdict-1.1.zip (12.9 kB 查看哈希

上传时间:

支持者

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面