0

I have a set of strings that I extracted and stored into an array. Some of these contain variables that I want to extract, the problem is these are strings at the moment. So for example, one string would look like

s1 = 'DataFile=scan1.dat'

Others would look like

s2 = 'NumberOfChannels=32'

What I want to do is take s1 and s2 and extract from them info and store them as such:

DataFile='scan1.dat'
NumberOfChannels=32

The strings all look similar to the ones above. It's either a variable that contains a string itself, or a variable containing an integer. Here's my (failed) attempt at the integer case:

            # ll is a string element of the big array

            if ll.startswith('NumberOfChannels'): 
                print "found nChans"
                idx = ll.index('=')
                vars()[ll[:idx-1]] = int(ll[idx+1:])

Any suggestions/external modules that could help me out would be greatly appreciated

1
  • 1
    It is a common question, but this practice is frowned upon in Python because it is not only dangerous (you can easily shadow a builtin) but also an horrid namespace pollution. Store key/values in a dict, a separate namespace (or use a dummy object as a namespace). Commented Mar 1, 2014 at 20:05

3 Answers 3

2
def convert(val):
    """
    Attempt to coerce type of val in following order: int, float, str
    """
    for type in (int, float, str):
        try:
            return type(val)
        except ValueError:
            pass
    return val

def make_config(*args, **kwargs):
    for arg in args:
        try:
            key,val = arg.split('=')
            kwargs[key.strip()] = convert(val.strip())
        except ValueError:   # .split() didn't return two items
            pass
    return kwargs

s1 = 'DataFile=scan1.dat'
s2 = 'NumberOfChannels=32'
config = make_config(s1, s2)

which gives you

{'DataFile': 'scan1.dat', 'NumberOfChannels': 32}
Sign up to request clarification or add additional context in comments.

1 Comment

+1 for this for being so easy to use, but why do you attempt to convert to str in the convert() function? The value is always str by default
1

While this is might not be the best way of achieving whatever you are trying, here is a way of doing it:

string_of_interest = 'NumberOfChannels=32'
string_split = string_of_interest.split('=')
globals() [ string_split[0] ] = string_split[1]

EDIT: (From comments), you can try

globals() [ string_split[0] ] = eval(string_split[1])

if you trust the type conversion.

3 Comments

alternatively, eval(ll,globals()) if you trust the input.
@isedev Have you tried using eval() in this case? It produces a SyntaxError exception.
yeah, it would for the string, not the integer. Good point :)
1

With a slight modification, you can use exec for this;

In [1]: exec('NumberOfChannels = 32')

In [2]: NumberOfChannels
Out[2]: 32

In [3]: exec('DataFile="scan1.dat"')

In [4]: DataFile
Out[4]: 'scan1.dat'

Note that you should never feed untrusted code to exec!

And loading random variables into your program is generally a bad idea. What if the variable names are the same as some used in your program?

If you want to store configuration data, have a look at json instead.

In [6]: import json

In [7]: json.dumps({'NumberOfChannels': 32, 'DataFile': 'scan1.dat'})
Out[7]: '{"DataFile": "scan1.dat", "NumberOfChannels": 32}'

In [8]: json.loads('{"DataFile": "scan1.dat", "NumberOfChannels": 32}')
Out[8]: {u'DataFile': u'scan1.dat', u'NumberOfChannels': 32}

In [9]: config = json.loads('{"DataFile": "scan1.dat", "NumberOfChannels": 32}')

In [10]: config['DataFile']
Out[10]: u'scan1.dat'

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.