以列表的形式获取指纹并访问每一个

2024-05-15 16:45:16 发布

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

from myfolder import typing_commands as tcm
import sys, StringIO
class InfoTest(StartUpTest):
    IS_TEST = True
    def __init__(self):
        super(InfoTest, self).__init__()

    def setup(self):
        return

    def runtest(self):
        tcm.erase_flash()
        self.boot() # boot method is defined in StartUpTest class
        time.sleep(20)
        tcm.info_read() #Here it prints all the info see o/p1

        #To get The printed data in list form
        old_stdout = sys.stdout
        capturer = StringIO.StringIO()
        sys.stdout = capturer
        tcm.info_read()
        sys.stdout = old_stdout
        output = capturer.getvalue().splitlines()

        for each in output[8:]:
            print each, type(each)
        print type(output)  #see o/p2
        return

开/关:

Info as desired:
Downloading Logs...
Info Downloaded!

####################
Info Entry 1:
####################
        Type                : Survey
        Survey_time         : 2014-09-05 10:10:40
        Inclination    (deg): 45
        Temperature     (C) : 30.00
        Battery_Voltage (mV): 24.0

o/p2编号:

        Survey_time         : 2014-09-05 10:11:44 <type 'str'>
        Inclination    (deg): 45 <type 'str'>
        Temperature     (C) : 30.00 <type 'str'>
        Battery_Voltage (mV): 24.0 <type 'str'>

<type 'list'>

现在我的问题是,虽然我能够得到列表形式的outputoutputeach实际上是一个str。我想检查Battery_Voltage是否在范围内,即大于20V,与其他电压相同,例如TemperatureInclination。我应该如何为每个提取值,以便对它们执行检查?我还必须硬编码它来接触我的一套支票

for each in output[8:]:
            print each, type(each)

有没有更好的办法


Tags: inselfinfooutputtimedeftypestdout
2条回答

还有一种方法更灵活,您可以更好地控制必须应用于这些值的条件。当有很多字段需要处理并且需要做一些更复杂的事情时,这可能会很有帮助

我们可以为每个字段动态调用特定于此特定描述的方法。例如,当处理描述为Battery的字段时,我们调用FieldProcessor类的process\u Battery,依此类推

所以在打印功能中:

for each in output[8:]:
            print each, type(each)

我会添加一些代码如下:

import re, sys
from collections import namedtuple

for each in output[8:]:

   # I prefer using namedtuple so we can use tuple.description and tuple.value
   field = namedtuple("field", "description value")

   # Regular expression for extracting the description and value
   # May be optimized, play with it :) takes description containing A-Z,a-z,_
   result = re.findall(r'^ *([A-Za-z_]*).*: (.*)$', each)
   if len(result):

       # Make namedtuple from tuple
       field = field._make(result[0])

       processor = FieldProcessor()

       # Get function of FieldProcessor with description name
       process_func = getattr(processor, 'process_'+field.description.lower(), None)

       if callable(process_func):
           process_func(field)

   else:
       print "Cannot parse field "+each

然后我们可以有FieldProcessor类,在这里你可以用你的值做任何事情。我希望将str转换为float等不会有问题

class FieldProcessor:
    def process_voltage(self, field):
        pass

    def process_inclination(self, field):
        # Converting to float, int, ...
        if field.value > 20:
            print "Inclination more then 20"

    def process_survey_time(self, field):
        pass

    def process_temperature(self, field):
        pass

好吧,当你获得output时,你会:

output = capturer.getvalue().splitlines()

现在。。。在这里,您从不将StringIO(即str)的内容转换为其他类型。output列表中的元素都是字符串,甚至那些您感兴趣的(output[8:])也是形式为some name: number的字符串,因此python可能无法神奇地理解您对数字部分感兴趣,并自动转换这些值

您希望显式转换这些字符串中表示的数字

要将字符串转换为数字,只需调用float(或int表示整数):

>>> float('1.0')
1.0
>>> type(float('1.0'))
<class 'float'>

在您的情况下,有些日期您不想转换。当您将它们传递给float时,它们将引发ValueError

例如:

import contextlib

capturer = StringIO.StringIO()
with contextlib.redirect_stdout(capturer):
    tcm.info_read()
output = capturer.getvalue().splitlines()

for line in output[8:]:
    name, value = line.split(':')
    try:
        value = float(value)
    except ValueError:
        # this is a date. Keep it as a string or do something else.
        pass
    print(name, ':', value, type(value))

如果您使用的是python<;3.4可以使用sys.__stdout__而不是^{}来恢复旧值:

sys.stdout = StringIO.StringIO()
tcm.info_read()
output = sys.stdout.getvalue().splitlines()
sys.stdout = sys.__stdout__

一旦你转换了你的值,你就可以用它们做所有你想要的检查(这可能取决于name部分)


正如我的建议:我将从该数据构建一个dict,这样您就可以方便地按名称访问不同的值:

data = {}
for line in output[8:]:
    name, value = line.split(':')
    try:
        value = float(value)
    except ValueError:
        # this is a date. Keep it as a string or do something else.
        pass
    data[name.strip().split()[0].lower()] = value

之后你可以做:

if data['temperature'] > 50:
    print('Temperature above 50 C')
elif data['battery_voltage'] < 20:
    print('Voltage too low')

相关问题 更多 >