获取打印在列表的形式,并访问每个那些
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
O/P1的:获取打印在列表的形式,并访问每个那些
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'>
现在我的问题是,虽然我能以列表形式获得output
,output
的each
实际上是str
。我想检查Battery_Voltage
是否在大于20V的范围内,并且像其他人一样。 Temperature
和Inclination
。我应该如何提取每个的值,以便我可以对它们执行检查?另外,我必须对它进行硬编码才能接触到我的一系列检查,例如。
for each in output[8:]:
print each, type(each)
有没有更好的方法来做到这一点?
那么,当你获得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,而不是contextlib.redirect_stdout
可以使用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')
还有另一种方法是更加灵活和你有过哪些必须适用于那些值的条件更好的控制。当有很多字段需要处理时,这可能会有帮助,并且您需要做一些更复杂的工作。
我们可能会动态地为每个字段调用特定于此特定说明的方法。例如,当正在处理描述电池的字段时,我们呼叫process_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浮动等问题。
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
谢谢吨..完美的作品! – tryPy 2014-09-05 19:08:28