0

I am relatively new on Python.

The program I am writing reads line by line a XML file using a while loop. The data read is split so the information that I get is something like:

datas = ['Name="Date"', 'Tag="0x03442333"', 'Level="Acquisition"', 'Type="String"']

-Inside my program, I want to assign to some variables called exactly as the word before the = sign, the information after the = sign in the previous strings. And then I will introduce them as attributes for a class (this already works) - What I have done until the moment is:

Name = ''
Tag = ''
Level = ''
Type = ''

for i in datas:
    exec(i)

-It works fine that way. However, I do not want to use the exec function. Is there any other way of doing that?

Thank you

1
  • Those who are wondering what's so bad about using exec or eval, please see Eval really is dangerous by SO veteran Ned Batchelder. Commented Apr 1, 2016 at 10:22

4 Answers 4

1

exec is generally the way to go about this. You could also add it to the globals() dictionary directly, but this would be slightly dangerous sometimes.

for pair in datas:
    name, value = pair.split("=")
    globals()[name] = eval(value)
Sign up to request clarification or add additional context in comments.

1 Comment

Using eval on unsanitized data isn't really any less dangerous than using exec.
1

You are right that you should avoid exec for security reasons, and you should probably keep the field values in a dict or similar structure. It's better to let a Python library do the whole parsing. For example, using ElementTree:

import xml.etree.ElementTree as ET
tree = ET.parse('myfile.xml')
root = tree.getroot()

and then iterating over root and its children, depending on how exactly your XML data looks like.

Comments

0

At most what you expect to do is discussed here. To convert string to variable name.

But what you should ideally do is to create a dictionary. Like this.

for i in datas:
    (key,value)=i.split("=")
    d[key] = eval(value)

NOTE: Still avoid using eval.

Comments

0

As Pelle Nilsson says, you should use a proper XML parser for this. However, if the data is simple and the format of your XML file is stable, you can do it by hand.

Do you have a particular reason to put this data into a class? A dictionary may be all you need:

datas = ['Name="Date"', 'Tag="0x03442333"', 'Level="Acquisition"', 'Type="String"']

datadict = {}
for s in datas:
    key, val = s.split('=')
    datadict[key] = val.strip('"')

print(datadict)

output

{'Tag': '0x03442333', 'Type': 'String', 'Name': 'Date', 'Level': 'Acquisition'}

You can pass such a dictionary to a class, if you want:

class MyClass(object):
    def __init__(self, data):
        self.__dict__ = data

    def __repr__(self):
        s = ', '.join('{0}={1!r}'.format(k,v) for k, v in self.__dict__.items())
        return 'Myclass({0})'.format(s)

a = MyClass(datadict)
print(a)
print(a.Name, a.Tag)

output

Myclass(Tag='0x03442333', Type='String', Name='Date', Level='Acquisition')
Date 0x03442333

All of the code in this answer should work correctly on any recent version of Python 2 as well as on Python 3, although if you run it on Python 2 you should put

from __future__ import print_function

at the top of the script.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.