我有一些日志文件看起来像以下几行:
<tickPrice tickerId=0, field=2, price=201.81, canAutoExecute=1>
<tickSize tickerId=0, field=3, size=25>
<tickSize tickerId=0, field=8, size=534349>
<tickPrice tickerId=0, field=2, price=201.82, canAutoExecute=1>
我需要定义一个类型为tickPrice或tickSize的类。在做定义之前,我需要决定使用哪个。
获取这些值的Pythonic方法是什么?换句话说,我需要一种有效的方法来反转类上的str()。
这些类已经定义,只包含呈现的变量,例如tickPrice.tickerId
。我试图找到一种从文本中提取这些值并设置实例属性以匹配的方法。
编辑:回答
这就是我最终做的事情 -
with open(commandLineOptions.simulationFilename, "r") as simulationFileHandle:
for simulationFileLine in simulationFileHandle:
(date, time, msgString) = simulationFileLine.split("\t")
if ("tickPrice" in msgString):
msgStringCleaned = msgString.translate(None, ''.join("<>,"))
msgList = msgStringCleaned.split(" ")
msg = message.tickPrice()
msg.tickerId = int(msgList[1][9:])
msg.field = int(msgList[2][6:])
msg.price = float(msgList[3][6:])
msg.canAutoExecute = int(msgList[4][15:])
elif ("tickSize" in msgString):
msgStringCleaned = msgString.translate(None, ''.join("<>,"))
msgList = msgStringCleaned.split(" ")
msg = message.tickSize()
msg.tickerId = int(msgList[1][9:])
msg.field = int(msgList[2][6:])
msg.size = int(msgList[3][5:])
else:
print "Unsupported tick message type"
答案 0 :(得分:2)
我不确定您希望如何在命名空间中动态创建对象,但以下内容至少会根据您的日志动态创建对象:
采取行动:
line = '<tickPrice tickerId=0, field=2, price=201.81, canAutoExecute=1>'
删除我们不感兴趣的字符,然后将该行拆分为列表:
line = line.translate(None, ''.join('<>,'))
line = line.split(' ')
为方便起见,列出潜在的类属性:
line_attrs = line[1:]
然后创建你的对象(名字,基本元组,attrs字典):
tickPriceObject = type(line[0], (object,), { key:value for key,value in [at.split('=') for at in line_attrs]})()
证明它按照我们的预期运作:
print(tickPriceObject.field)
# 2
答案 1 :(得分:1)
接近正则表达式的问题,但结果与特里斯坦的出色答案相同(并且窃取了他对type
构造函数的使用,这是我永远无法记住的)
import re
class_instance_re = re.compile(r"""
<(?P<classname>\w[a-zA-Z0-9]*)[ ]
(?P<arguments>
(?:\w[a-zA-Z0-9]*=[0-9.]+[, ]*)+
)>""", re.X)
objects = []
for line in whatever_file:
result = class_instance_re.match(line)
classname = line.group('classname')
arguments = line.group('arguments')
new_obj = type(classname, (object,),
dict([s.split('=') for s in arguments.split(', ')]))
objects.append(new_obj)