在回答之前请仔细阅读这个问题,因为这不是你所想的。。。我正在研究如何创建python对象包装器来表示系统上的硬件设备(下面的示例经过修剪)。在
class TPM(object):
@property
def attr1(self):
"""
Protects value from being accidentally modified after
constructor is called.
"""
return self._attr1
def __init__(self, attr1, ...):
self._attr1 = attr1
...
@classmethod
def scan(cls):
"""Calls Popen, parses to dict, and passes **dict to constructor"""
大多数构造函数输入都涉及在中运行命令行输出子流程.Popen然后分析输出以填充对象属性。我已经想出了一些方法来处理这些问题,但我对目前为止所做的工作并不满意,我正在努力寻找更好的解决办法。以下是我发现的常见陷阱。(简要说明:工具版本受到严格控制,因此解析的输出不会意外更改。)
许多工具产生不同的输出,有时包括字段,有时不包括字段。这意味着,如果您组装一个dict来包装在容器对象中,那么构造器或多或少会被迫使用**kwargs,而实际上并没有定义字段。我不喜欢这样,因为它使得通过pylint等进行的静态分析不那么有用。sphinx的定义更清晰,更容易检测到错误。
为了代替**kwargs,我还尝试将许多字段的默认参数设置为None,结果是非常糟糕的。关于这个选项,我非常不喜欢的一点是可选字段并不总是出现在命令行工具输出的末尾。这使得查看构造函数并将其与工具输出相匹配有点费心。
我非常希望一开始就避免构建字典,但是使用setattr创建属性会使pylint无法检测到\u attr1,等等。。。并创建警告。欢迎有任何想法。。。
基本上,我在寻找一种合适的Python式的方法。我的要求如下:
在Python中有没有一种很好的方法(希望没有大量的样板代码)?如果是,那是什么?在
编辑:
根据一些澄清请求,我们可以查看tpm_version命令。这是我的笔记本电脑的输出,但是对于这个TPM,它并没有包含所有可能的属性。有时,命令会返回我也想捕获的额外属性。这使得解析容器对象上的已知属性名相当困难。在
^{pr2}$示例代码(请忽略缺少健全性检查。精简):
def __init__(self, chip_version, spec_level, errata_revision,
tpm_vendor_id, vendor_specific_data, tpm_version,
manufacturer_info):
self._chip_version = chip_version
...
@classmethod
def scan(cls):
tpm_proc = Popen("/usr/sbin/tpm_version")
stdout, stderr = Popen.communicate()
tpm_dict = dict()
for line in tpm_proc.stdout.splitlines():
if "Version Info:" in line:
pass
else:
split_line = line.split(":")
attribute_name = (
split_line[0].strip().replace(' ', '_').lower())
tpm_dict[attribute_name] = split_line[1].strip()
return cls(**tpm_dict)
这里的问题是,这个(或者一个我可能无法查看源代码以获取每个可能的字段)可能会添加额外的东西,导致解析器正常工作,但我的对象无法捕获字段。这就是我真正想用优雅的方式解决的问题。在
在过去的几个月里,我一直在寻找一个更可靠的答案,因为我基本上是在硬件支持库上工作,最后得出了一个令人满意的(虽然相当冗长)答案。在
相关问题 更多 >
编程相关推荐