Hi,
Is it possible to convert a string to a function parameter?
Ex:
str = 'True, type=rect, sizes=[3, 4]'
and I should be able to use it as:
test(convert(str)) and the behaviour should be same as calling test
with those values :
i.e. test(True, type=rect, sizes=[3, 4])
I tried eval, but it did not work. And any other mechanism I think
turns out to be creating a full fledged python parser.
Is there any mechanism with which we can do this straight away?
I heard 'pyparsing' was good. ...Not that I've even been to its
webpage.
Did someone say 'pyparsing'?
Here is a first cut (partially lifted
from a previous post):
from pyparsing import *
LPAR,RPAR,LBRACK,RBRACK,EQ,COMMA = map(Suppress,"()[]=,")
noneLiteral = Literal("None")
boolLiteral = oneOf("True False")
integer = Combine(Optional(oneOf("+ -")) + Word(nums)).setName
("integer")
real = Combine(Optional(oneOf("+ -")) + Word(nums) + "." +
Optional(Word(nums))).setName("real")
ident = Word(alphas+"_",alphanums+"_")
listStr = Forward().setName("list")
tupleStr = Forward().setName("tuple")
listItem = real | integer | noneLiteral | boolLiteral | \
quotedString.setParseAction(removeQuotes) | Group(listStr) |
tupleStr | ident
listStr << ( LBRACK + Optional(delimitedList(listItem)) + Optional
(COMMA) + RBRACK )
tupleStr << (LPAR + Optional(delimitedList(listItem)) + Optional
(COMMA) + RPAR)
# parse actions perform parse-time conversions
noneLiteral.setParseAction(lambda: None)
boolLiteral.setParseAction(lambda toks: toks[0]=="True")
integer .setParseAction(lambda toks: int(toks[0]))
real .setParseAction(lambda toks: float(toks[0]))
listStr .setParseAction(lambda toks: toks.asList())
tupleStr .setParseAction(lambda toks: tuple(toks.asList()))
arg = Group(ident("varname") + EQ + listItem("varvalue")) | listItem
argstring = 'True, type=rect, sizes=[3, 4,], coords = ([1,2],[3,4])'
parsedArgs = delimitedList(arg).parseString(argstring)
args = []
kwargs = {}
for a in parsedArgs:
if isinstance(a,ParseResults):
if isinstance(a.varvalue,ParseResults):
val = a.varvalue.asList()
else:
val = a.varvalue
kwargs[a.varname] = val
else:
args.append(a)
print "Args:", args
print "Kwargs:", kwargs
Prints:
Args: [True]
Kwargs: {'coords': ([1, 2], [3, 4]), 'type': 'rect', 'sizes': [3, 4]}