用解析/切片子字符串的内容实例化对象属性?

2024-10-01 11:20:40 发布

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

Python专家

问题如下:

我有一个用JSON进行的大型机AS/400提取,它被处理成一个“长”的单个字符串,以便进一步切片/子字符串(如果这是一个词的话)。解析结果将创建具有多个属性的模型实例。这些属性生成一个OrderedDict()以再次序列化(这是因为在将来,数据源可能会更改,我需要在这个级别维护抽象)。我从最近的研究中了解到,将''(空字符串)作为None来维护属性/数据的最佳方法是在将来进行最佳分析。你知道吗

for i, line in enumerate(data_json):
    swap_string += line['data']
    if data_json[i] == data_json[-1] or data_json[i+1]['data'][1] == '_':
        swap_list.append(swap_string)
        swap_string = ''

以下是原始结果:

_ D 958.860 L B NA0.000 010 N 001 U 0 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 999 T00 000 99 999 -/- 001 BG/CODEBEDINGUNGEN : BG F04/F07/F20;

然后,有了这个字符串,我就有了一个“map”或“header”来生成可以序列化的对象,切片等等:

slices = ['3:23', '23:24', '26:27', '29:38', '39:42', '43:46', '48:50', '51:52', '53:54', '55:58', '61:67', '72:79']

然后,我请求类实例化并创建以下属性:

def __init__(self, bm=None, kg=None, abm_saa=None, la=None, lt=None,
                   bu_su=None, pos=None, hws=None, sp=None, r=None, p=None,
                   asa=None, em_ab=None, em_bis=None, benennung=None,
                   asb=None, t_a=None, vkfbez=None, pws1=None, qu1=None,
                   pws2=None, qu2=None, da=None, anz=None, t_b=None,
                   bg=None, code=None, pruef=None, add_info=None):
    self.bm = bm
    self.kg = kg
    self.abm_saa = abm_saa...

然后问题来了:

我的问题是:使用具有切片定界的列表,如何将具有for循环的对象实例化为应用列表理解的正确属性?是否也可以使用类中的属性执行循环?另外,用一个简单的if语句将空字符串作为None应用到对象中?你知道吗

for data in swap_list:
    for slice_str in slices:
        agr = PdsAGRMZDataModels()
        agr.abm_saa = data[slice_str].strip()
        agr.la = data[slice_str].strip()

Tags: 对象实例字符串inselfnonejsonfor
1条回答
网友
1楼 · 发布于 2024-10-01 11:20:40

我看不到切片数组中的值与上面显示的原始字符串之间的相关性,但根据其余的解释,我相信您可以按以下步骤进行:

1)将切片数组转换为可用作字符串范围的数字形式:(仅当每行数据的范围相同时才执行一次)

ranges = [ (int(r[0]),int(r[1])) for r in [ s.split(":") for s in slices] ]

2)对于数据集中的每一行,根据范围提取参数值:

params = [ [p,None][p==''] for p in [ line[start:end].strip() for start,end in ranges ] ]

# Note: [p,None][p==''] is a compact alternative to:  None if p == '' else p

3)使用参数值列表和解包(*)来实例化模型对象:(这假设切片范围与构造函数的参数顺序相同)

agr = PdsAGRMZDataModels(*params)

# Based on your sample data and slices this would produce seemingly
# misaligned data content.  
#
# agr.bm       == '958.860 L B NA0.000'
# agr.kg       == None
# agr.abm_saa  == '0'
# ...

[编辑]避免位置问题:

如果要解决参数位置/计数约束,可以对切片定义使用字典结构,以便提取的数据获得与函数参数匹配的关联名称。你知道吗

例如:

 slices = { 'kg':(3,23), 'bm':(23,24), 'xyz':(5,52) }

使用切片字典,行的数据也可以在字典中生成命名值:

 data = { p:[v,None][v==''] for p,v in [(p,line[r[0]:r[1]].strip()) for p,r in slices.items()] }

然后,您可以使用inspect模块获取PdsAGRMZDataModels()构造函数的参数列表,并按正确的顺序将它们映射到您拥有的命名值(对于您没有的值,使用None)。此映射将始终以适当的顺序生成正确数量的参数(与源数据无关)。你知道吗

[编辑]:getargspec到getfullargspec

 import inspect
 params = [data[arg] if arg in data else None for arg in inspect.getfullargspec(PdsAGRMZDataModels).args[1:]]
 # Note that, because we're calling a method, I'm dropping 
 # the first argument which corresponds to "self" and doesn't count.

有了它,您可以使用任何源数据安全地调用模型构造函数,您的解决方案将对API更改或输入结构更改具有更大的弹性。如果要从同一个数据调用多个不同的函数(使用不同的参数名),甚至可以为同一个片指定多个名称。你知道吗

agr = PdsAGRMZDataModels(*params)
# The constructor gets bm= and kg= in the right order, 
# and None for all other parameters.  
# The xyz value is ignored since PdsAGRMZDataModels() has no such parameter.  

相关问题 更多 >