1

I am trying to write a dynamic program(to parse json files based on their tags) in python and i am using Python exec function to do that. But the program is failing when exec statement is in a function.

RUN 1: Exec in a function:

import json from pandas.io.json import json_normalize import sys def param(dfile): aString = "['widget']['image']~['widget']['window']~['widget']['text']" for nd_part in aString.split('~'): exec("temp = %s%s"%(dfile,nd_part)) print(temp) if __name__ == "__main__": dfile = json.load(open("sample_json.json")) str_list = param(dfile) 

JSON Data: sample_json.json

{"widget": { "debug": "on", "window": { "title": "Sample Konfabulator Widget", "name": "main_window", "width": 500, "height": 500 }, "image": { "src": "Images/Sun.png", "name": "sun1", "hOffset": 250, "vOffset": 250, "alignment": "center" }, "text": { "data": "Click Here", "size": 36, "style": "bold", "name": "text1", "hOffset": 250, "vOffset": 100, "alignment": "center", "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" } }} 

Error:

Traceback (most recent call last): File "sample_test_json.py", line 12, in <module> str_list = param(dfile) File "sample_test_json.py", line 9, in param print(temp) NameError: name 'temp' is not defined 

RUN 2: EXEC in main:

import json from pandas.io.json import json_normalize import sys if __name__ == "__main__": dfile = json.load(open("sample_json.json")) aString = "['widget']['image']~['widget']['window']~['widget']['text']" for nd_part in aString.split('~'): exec("temp = %s%s"%(dfile,nd_part)) print(temp) 

JSON Data: sample_json.json(same data as above)

Output: No error(Result as expected)

{'hOffset': 250, 'vOffset': 250, 'name': 'sun1', 'alignment': 'center', 'src': 'Images/Sun.png'} {'width': 500, 'height': 500, 'name': 'main_window', 'title': 'Sample Konfabulator Widget'} {'data': 'Click Here', 'hOffset': 250, 'vOffset': 100, 'size': 36, 'style': 'bold', 'onMouseUp': 'sun1.opacity = (sun1.opacity / 100) * 90;', 'name': 'text1', 'alignment': 'center'} 

RUN 3: I tried eval and tried formatting the string from this post. How to return value from exec in function?

import json from pandas.io.json import json_normalize import sys def param(dfile): aString = "['widget']['image']~['widget']['window']~['widget']['text']" for nd_part in aString.split('~'): exec('temp = "{}""{}"'.format(dfile,nd_part)) print(temp) if __name__ == "__main__": dfile = json.load(open("sample_json.json")) str_list = param(dfile) 

Error:

Traceback (most recent call last): File "sample_test_json.py", line 12, in <module> str_list = param(dfile) File "sample_test_json.py", line 9, in param print(temp) NameError: name 'temp' is not defined 

Please help me in identifying the issue. Thanks in advance.

6
  • 2
    You will probably have better luck using eval() but really, there's no need for that either. Commented Oct 16, 2017 at 15:51
  • You're just trying to set the variable. There's no need for exec() Commented Oct 16, 2017 at 15:52
  • yes. But my original requirement is to create a dataframe from each tag and write into delimiter file. My program should be dynamic to handle multiple tags and create multiple files base on number of tags (planning to pass those tags as paramaters to this program). Commented Oct 16, 2017 at 15:54
  • @kindall let me try eval() Commented Oct 16, 2017 at 16:14
  • Thanks @kindall. eval() is working. I will post my answer Commented Oct 16, 2017 at 16:17

2 Answers 2

1

Using Eval() i am getting the result i exepcted. Posting answer below. But still i am not sure why exec() is not working.

import json from pandas.io.json import json_normalize import sys def param(dfile): aString = "['widget']['image']~['widget']['window']~['widget']['text']" for nd_part in aString.split('~'): s = '{0}{1}'.format('dfile',nd_part) temp = eval(s) print(temp) if __name__ == "__main__": dfile = json.load(open("sample_json.json")) str_list = param(dfile) 

Result:

{'src': 'Images/Sun.png', 'alignment': 'center', 'vOffset': 250, 'name': 'sun1', 'hOffset': 250} {'title': 'Sample Konfabulator Widget', 'height': 500, 'width': 500, 'name': 'main_window'} {'alignment': 'center', 'onMouseUp': 'sun1.opacity = (sun1.opacity / 100) * 90;', 'data': 'Click Here', 'hOffset': 250, 'size': 36, 'vOffset': 100, 'name': 'text1', 'style': 'bold'} 
Sign up to request clarification or add additional context in comments.

Comments

1

I think exec add temp to global. So add global temp before print temp may be useful

import json from pandas.io.json import json_normalize import sys def param(dfile): global temp aString = "['widget']['image']~['widget']['window']~['widget']['text']" for nd_part in aString.split('~'): exec("temp = %s%s"%(dfile,nd_part)) print(temp) if __name__ == "__main__": dfile = json.load(open("sample_json.json")) str_list = param(dfile) 

should be fine.

Or you can also do things like

import json from pandas.io.json import json_normalize import sys def param(dfile): d={} aString = "['widget']['image']~['widget']['window']~['widget']['text']" for nd_part in aString.split('~'): exec("temp = %s%s"%(dfile,nd_part),d) print(d['temp']) if __name__ == "__main__": dfile = json.load(open("sample_json.json")) str_list = param(dfile) 

2 Comments

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From Review

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.