将命令行输出解析为容器对象的python方法

2024-09-21 10:36:45 发布

您现在位置:Python中文网/ 问答频道 /正文

在回答之前请仔细阅读这个问题,因为这不是你所想的。。。我正在研究如何创建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然后分析输出以填充对象属性。我已经想出了一些方法来处理这些问题,但我对目前为止所做的工作并不满意,我正在努力寻找更好的解决办法。以下是我发现的常见陷阱。(简要说明:工具版本受到严格控制,因此解析的输出不会意外更改。)

  1. 许多工具产生不同的输出,有时包括字段,有时不包括字段。这意味着,如果您组装一个dict来包装在容器对象中,那么构造器或多或少会被迫使用**kwargs,而实际上并没有定义字段。我不喜欢这样,因为它使得通过pylint等进行的静态分析不那么有用。sphinx的定义更清晰,更容易检测到错误。

  2. 为了代替**kwargs,我还尝试将许多字段的默认参数设置为None,结果是非常糟糕的。关于这个选项,我非常不喜欢的一点是可选字段并不总是出现在命令行工具输出的末尾。这使得查看构造函数并将其与工具输出相匹配有点费心。

  3. 我非常希望一开始就避免构建字典,但是使用setattr创建属性会使pylint无法检测到\u attr1,等等。。。并创建警告。欢迎有任何想法。。。

基本上,我在寻找一种合适的Python式的方法。我的要求如下:

  1. 命令行工具输出解析为容器对象。在
  2. 容器对象通过构造后的属性保护属性。在
  3. 不同数量的输入到构造函数,工作静态分析和错误检测丢失的必需字段在运行时。在

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

这里的问题是,这个(或者一个我可能无法查看源代码以获取每个可能的字段)可能会添加额外的东西,导致解析器正常工作,但我的对象无法捕获字段。这就是我真正想用优雅的方式解决的问题。在


Tags: 工具对象命令行self属性versiondefline
1条回答
网友
1楼 · 发布于 2024-09-21 10:36:45

在过去的几个月里,我一直在寻找一个更可靠的答案,因为我基本上是在硬件支持库上工作,最后得出了一个令人满意的(虽然相当冗长)答案。在

  1. 将工具输出(不管它们看起来是什么)解析成与工具如何查看设备相匹配的对象结构。它们可以有非常通用的dict结构,但应该尽可能多地拆分。在
  2. 在使用属性访问工具容器对象中的项的容器类的基础上创建另一个容器类。这强制了一个API,并且可以在工具的多个版本和不同的工具输出之间返回正常的错误!在

相关问题 更多 >

    热门问题