Generating python data structures from parsed text without eval() -


i'm trying build tool generate datastructures text config. usepyparsing parse commands...

config file:

add iteration name = "cisco 10m/half"     append observation name = "packet loss"         assign observation results_text = 0.0         assign observation results_bool = true         append datapoint             assign datapoint metric = txpackets             assign datapoint units = packets 

pyparsing commands

['add', 'iteration', ['name', 'cisco 10m/half']] ['append', 'observation', ['name', 'packet loss']] ['assign', 'observation', ['results_text', '0']] ['assign', 'observation', ['results_bool', 'true']] ['append', 'datapoint'] ['assign', 'datapoint', ['metric', 'txpackets']] ['assign', 'datapoint', ['units', 'packets']] 

the first column command verb, , second name of class i've defined.

right now, solution can come building resultant data structure looks this:

if cmd == 'add':     obj = eval('%s()' % (txtobj))  # create testdata object 

in case of first command, needs call iteration(), name of class have imported parser.

is there way build classes text config without resorting eval()? if so, how it?

edit:

sven's answer assumed had classes created, dynamically creating classes part of problem.

this how can create new class named 'child' dynamically, assuming parent class named parent in code...

>>> child_name = "child" >>> child_parents = (parent,) >>> child body = """ def __init__(self, arg1):     # initialization child class     self.foo = do_something(arg1) """ >>> child_dict = {} >>> exec(child_body, globals(), child_dict) >>> childobj = type(child_name, child_parents, child_dict) >>> childobj.__name__ 'child' >>> childobj.__bases__ (<type 'object'>,) >>> # instantiating new child object... >>> childinst = childobj() >>> childinst <__main__.child object @ 0x1c91710> >>> 

if need create global or local variable dynamically, should avoid globals() , use dict()...

>>> vars = {} >>> varname = 'foo' >>> vars[varname] = true >>>  

in comment, asked how generate dynamic keywords method calls... such as:

eval('log.append(%s._replace(%s = val))' % (objtxt, key) 

the solution use sven's answer (below) class instance, , mapping (i.e. dict) in method args...

classes = dict((c.__name__, c) c in [iteration,observation,datapoint]) # ... obj = classes[txtobj]() log.append(obj._replace(**{"%s" % key: val})) 

judging eval() call, looks classes trying instantiate in current global scope. can them , create instance:

obj = globals()[txtobj]() 

note call global object named txtobj, should not use untrusted data.

it might better create own dictionary of allowed classes:

classes = dict((c.__name__, c) c in [iteration,observation,datapoint]) # ... obj = classes[txtobj]() 

Comments

Popular posts from this blog

php - What is the difference between $_SERVER['PATH_INFO'] and $_SERVER['ORIG_PATH_INFO']? -

fortran - Function return type mismatch -

queue - mq_receive: message too long -