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