понимание строк в Python - PullRequest
       3

понимание строк в Python

0 голосов
/ 17 августа 2011

Я работаю с изображениями, которые имеют несколько слоев, которые описаны в их метаданных, которые выглядят следующим образом ..

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] .mode

"Normal"

В другом посте кто-то показал мне, как получить названия каждого слоя, что было очень полезно, но теперь я собираюсь использовать другую информацию. PS: если это поможет, мне наплевать на информацию внутри {} Спасибо

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

Ответы [ 2 ]

0 голосов
/ 17 августа 2011

Если вы не хотите иметь дело с регулярным выражением ...

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

0 голосов
/ 17 августа 2011

Синтаксический анализ ( 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 (), но это намного сложнее, медленнее и создает угрозу безопасности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...