Python 中的字符串理解

发布于 2024-11-29 19:06:34 字数 607 浏览 0 评论 0原文

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

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].模式

"Normal"

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

print type(layers)
<type 'str'>"

I am working with images that have multiple layer which are described in their meta data that looks like this..

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}

I'm wondering if this formatting could be recognizable by Python as more then a string. Ideally I would like to call up the properties of any one for the layers. For example:

print layers[0].mode

"Normal"

On another post someone showed me how to get the names of each layer, which was very helpful, but now I'm looking to use the other info.
PS: if it helps I don't care about any of the info inside the {}
Thanks

print type(layers)
<type 'str'>"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冷情 2024-12-06 19:06:34

如果您不想处理正则表达式...

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') 

输出...

Cube1 ... mode: Normal

Ground ... opacity: 186

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

In case you don't want to deal with 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') 

output ...

Cube1 ... mode: Normal

Ground ... opacity: 186

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

白馒头 2024-12-06 19:06:34

解析(Pyparsing 等)无疑是正确且可扩展的方法,但这是一种快速而肮脏的方法使用正则表达式和推导式来解析属性并使用 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)

我将所有命令式代码移至 __init__() 或类方法 Layers.make_list_from_string() 中。
目前它将所有参数存储为字符串,它不认为不透明度是 int/float,但这只是一个额外的 try... except 块。

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

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() ,但这更令人讨厌、更慢并且存在安全风险。

Parsing (Pyparsing et al) is surely the correct and extensible way to go, but here's a fast-and-dirty object and constructors using regexes and comprehensions to parse properties and bolt them on with setattr(). All constructive criticisms welcome!

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)

I moved all the imperative code into __init__() or the classmethod Layers.make_list_from_string().
Currently it stores all args as string, it doesn't figure opacity is int/float, but that's just an extra try...except block.

Hey, it does the job you wanted. And as a bonus it throws in mutability:

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'

"I'm wondering if this formatting could be recognizable by Python as more then a string."

Alternatively, I was thinking if you tweaked the format a little, eval()/exec() could be used, but that's yukkier, slower and a security risk.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文