Python中的字符串理解

Python中的字符串理解,python,string,metadata,Python,String,Metadata,我正在处理具有多层的图像,这些图像在元数据中描述,如下所示 print layers Cube1[visible:true, mode:Normal]{r:Cube1.R, g:Cube1.G, b:Cube1.B, a:Cube1.A}, Ground[visible:true, mode:Lighten, opacity:186]{r:Ground.R, g:Ground.G, b:Ground.B, a:Ground.A}, Cube3[visible:true, mode:Normal]

我正在处理具有多层的图像,这些图像在元数据中描述,如下所示

print layers
Cube1[visible:true, mode:Normal]{r:Cube1.R, g:Cube1.G, b:Cube1.B, a:Cube1.A}, Ground[visible:true, mode:Lighten, opacity:186]{r:Ground.R, g:Ground.G, b:Ground.B, a:Ground.A}, Cube3[visible:true, mode:Normal]{r:Cube3.R, g:Cube3.G, b:Cube3.B, a:Cube3.A}
我想知道Python是否能够识别这种格式,而不仅仅是字符串。理想情况下,我想调用任何一个图层的属性。例如:

打印图层[0]。打印模式

“正常”

在另一篇文章中,有人告诉我如何获取每一层的名称,这非常有用,但现在我想使用其他信息。 PS:如果有帮助的话,我不关心{}中的任何信息 谢谢

打印类型(图层)
"
解析(等)无疑是正确且可扩展的方法,但这里有一个快速且肮脏的对象和构造函数,它使用正则表达式和理解来解析属性,并用
setattr()
将它们连接起来。欢迎所有建设性的批评

import re
#import string

class Layer(object):
    @classmethod
    def make_list_from_string(cls,s):
        all_layers_params = re.findall(r'(\w+)\[([^\]]+)\]',s)
        return [cls(lname,largs) for (lname, largs) in all_layers_params]        
    def __init__(self,name,args):
        self.name = name
        for (larg,lval) in re.findall(r'(\w+):(\w+)(?:,\w*)?', args):
            setattr(self,larg,lval)                
    def __str__(self):
        return self.name + '[' + ','.join('%s:%s' % (k,v) for k,v in self.__dict__.iteritems() if k!='name') + ']'
    def __repr__(self):
        return self.__str__()

t = 'Cube1[visible:true, mode:Normal]{r:Cube1.R, g:Cube1.G, b:Cube1.B, a:Cube1.A}, Ground[visible:true, mode:Lighten, opacity:186]{r:Ground.R, g:Ground.G, b:Ground.B, a:Ground.A}, Cube3[visible:true, mode:Normal]{r:Cube3.R, g:Cube3.G, b:Cube3.B, a:Cube3.A}'
layers = Layer.make_list_from_string(t)
我将所有命令式代码移到
\uuuu init\uuuu()
或classmethod
层中。从\u string()
生成\u列表。 目前它将所有参数存储为字符串,它没有将不透明度设置为int/float,但这只是一个额外的
try…除了

嘿,它完成了你想要的工作。作为一个额外的奖励,它带来了可变性:

print layers[0].mode
'Normal'
print layers[1].opacity
'186'
print layers[2]
Cube3[visible:true,mode:Normal]
layers[0].mode = 'Weird'
print layers[0].mode
'Weird'
“我想知道Python是否能够识别这种格式,而不仅仅是字符串。”


或者,我在想,如果您稍微调整一下格式,可以使用eval()/exec(),但这样做会更麻烦、速度更慢并且存在安全风险。

如果您不想处理regex

layers = "Cube1[visible:true, mode:Normal]{r:Cube1.R, g:Cube1.G, b:Cube1.B, a:Cube1.A}, Ground[visible:true, mode:Lighten, opacity:186]{r:Ground.R, g:Ground.G, b:Ground.B, a:Ground.A}, Cube3[visible:true, mode:Normal]{r:Cube3.R, g:Cube3.G, b:Cube3.B, a:Cube3.A}"


layer_dict = {}

parts = layers.split('}')
for part in parts:
    part = part.strip(', ')

    name_end = part.find('[')
    if name_end < 1:
        continue
    name = part[:name_end]
    attrs_end = part.find(']')
    attrs = part[name_end+1:attrs_end].split(', ')
    layer_dict[name] = {}
    for attr in attrs:
        attr_parts = attr.split(':')
        layer_dict[name][attr_parts[0]] = attr_parts[1]        


print 'Cube1 ... mode:', layer_dict.get('Cube1').get('mode')
print 'Ground ... opacity:', layer_dict.get('Ground').get('opacity')
print 'Cube3', layer_dict.get('Cube3') 
layers=“Cube1[visible:true,mode:Normal]{r:Cube1.r,g:Cube1.g,b:Cube1.b,a:Cube1.a},Ground[visible:true,mode:light,opacity:186]{r:Ground.r,g:Ground.g,b:Ground.b,a:Ground.a},Cube3[visible:true,mode:Normal]{:Cube3.r,g:Cube3.g,b:Cube3.b,a}”
层_dict={}
零件=层。拆分(“}”)
对于部分中的部分:
零件=零件带(',')
name_end=part.find(“[”)
如果名称_end<1:
持续
名称=零件[:名称\u结束]
attrs_end=part.find(']'))
attrs=part[name\u end+1:attrs\u end].split(“,”)
层名称[名称]={}
对于属性中的属性:
attr_parts=attr.split(“:”)
图层名称[name][attr_parts[0]]=attr_parts[1]
打印'Cube1…mode:',layer_dict.get('Cube1')。get('mode'))
打印'Ground…opacity:',layer_dict.get('Ground')。get('opacity'))
打印'Cube3',图层记录获取('Cube3')
输出

立方1…模式:正常

地面…不透明度:186


Cube3{'visible':'true','mode':'Normal'}

我建议只分析行。我猜层不是字符串。如果是这样,请使用适当的方法获取所需信息。如果是字符串,请使用打印类型(层)查找,这将很容易用正则表达式进行分析。我要注意,
打印层[0]
命令位于
这可能是您的问题的一部分。看起来层是某种类型的对象,可能是多维数据集对象的包装器。如果您告诉我们这是从哪个框架或库来的,这会有所帮助。Fwiw,Python不要求类具有显式构造函数;您不需要提供层的空
\uuuuu init\uuuuu
函数。
\uuuuu init\uuuu()
不再为空,我将正则表达式解析移到其中。@lacrossj,如果它回答了您的问题,请不要忘记单击“接受”。
layers = "Cube1[visible:true, mode:Normal]{r:Cube1.R, g:Cube1.G, b:Cube1.B, a:Cube1.A}, Ground[visible:true, mode:Lighten, opacity:186]{r:Ground.R, g:Ground.G, b:Ground.B, a:Ground.A}, Cube3[visible:true, mode:Normal]{r:Cube3.R, g:Cube3.G, b:Cube3.B, a:Cube3.A}"


layer_dict = {}

parts = layers.split('}')
for part in parts:
    part = part.strip(', ')

    name_end = part.find('[')
    if name_end < 1:
        continue
    name = part[:name_end]
    attrs_end = part.find(']')
    attrs = part[name_end+1:attrs_end].split(', ')
    layer_dict[name] = {}
    for attr in attrs:
        attr_parts = attr.split(':')
        layer_dict[name][attr_parts[0]] = attr_parts[1]        


print 'Cube1 ... mode:', layer_dict.get('Cube1').get('mode')
print 'Ground ... opacity:', layer_dict.get('Ground').get('opacity')
print 'Cube3', layer_dict.get('Cube3')