I was converting the string to python dictionay thru ast.literal_eval()
. The string contains boolean values so the ast.literal_eval()
getting ValueError
.
From googling, I found that I have to add the statement ast.literal_eval(json.dumps(json.loads(data)))
to handle boolen data.
But, I'm still getting the same error.
Here is the code snippet:
#!/usr/bin/python
import sys
import os
import ast
import json
def main(argv):
data = argv[1]
print(argv[1])
crldix = ast.literal_eval(json.dumps(json.loads(data)))
for drive in crldix['files']:
print("|{}|{}|".format(drive['name'], drive['boolkey']))
return 0
if __name__ == "__main__":
retval = main(sys.argv)
exit(retval)
#eof
Output:
./test.py '{ "files": [ { "name": "filename", "boolkey": false } ] } '
Traceback (most recent call last):
File "./test.py", line 20, in <module>
retval = main(sys.argv)
File "./test.py", line 12, in main
crldix = ast.literal_eval(json.dumps(json.loads(data)))
File "/usr/lib/python2.7/ast.py", line 80, in literal_eval
return _convert(node_or_string)
File "/usr/lib/python2.7/ast.py", line 63, in _convert
in zip(node.keys, node.values))
File "/usr/lib/python2.7/ast.py", line 62, in <genexpr>
return dict((_convert(k), _convert(v)) for k, v
File "/usr/lib/python2.7/ast.py", line 60, in _convert
return list(map(_convert, node.elts))
File "/usr/lib/python2.7/ast.py", line 63, in _convert
in zip(node.keys, node.values))
File "/usr/lib/python2.7/ast.py", line 62, in <genexpr>
return dict((_convert(k), _convert(v)) for k, v
File "/usr/lib/python2.7/ast.py", line 79, in _convert
raise ValueError('malformed string')
ValueError: malformed string
ast.literal_eval(json.dumps(json.loads(data)))
is superfluous and redundant (see what I did here?)
json.loads
already returns a dictionary, so there's no need to turn it back to a string then back to a dict with literal_eval
.
Since json.loads('{ "files": [ { "name": "filename", "boolkey": false } ] } ')
works, any problem you have is due to the way your terminal passes the string to sys.argv
.
I don't know what OS/terminal you are using, but usually "
is required in order to pass an argument with spaces. This will mean that you have to escape the other "
in the string.
For example, on Windows, executing
import sys
import json
print(json.loads(sys.argv[1]))
In the following way (note the \\
used for escaping)
python test.py "{ \"files\": [ { \"name\": \"filename\", \"boolkey\": false } ] } "
works, outputting:
{'files': [{'name': 'filename', 'boolkey': False}]}
Another approach, without the need to escape "
:
import sys
import json
print(json.loads(sys.argv[1].replace("'", '"')))
Then executing
python test.py "{ 'files': [ { 'name': 'filename', 'boolkey': false } ] }"
works just as well.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.