开发者

creating variables from external data in python script

I want to read an external data source (excel) and create variables containing the data. Suppose the data is in columns and each column has a header with the variable na开发者_运维知识库me.

My first idea is to write a function so i can easily reuse it. Also, I could easily give some additional keyword arguments to make the function more versatile.

The problem I'm facing is that I want to refer to the data in python (interactively) via the variable names. I don't know how to do that (with a function). The only solution I see is returning the variable names and the data from my function (eg as lists), and do something like this:

def get_data()
    (...)
    return names, values

names, values = get_data(my_excel)

for n,v in zip(names, values):
    exec(''.join([n, '= v']))

Can I get the same result directly? Thanks, Roel


Use a dictionary to store your mapping from name to value instead of creating local variable.

def get_data(excel_document):
    mapping = {}
    mapping['name1'] = 'value1'
    # ...
    return mapping

mapping = get_data(my_excel)
for name, value in mapping:
    # use them

If you really want to populate variables from the mapping, you can modify globals() (or locals()), but it is generally considered bad practice.

mapping = get_data(my_excel)
globals().update(mapping)


If you just want to set local variables for each name in names, use:

for n, v in zip(names, values):
    locals()[n] = v

If you'd rather like to have a single object to access the data, which is much cleaner, simply use a dict, and return that from your function.

def get_data():
    (...)
    return dict(zip(names, values))

To access the value of the name "a", simply use get_data()["a"].

Finally, if you want to access the data as attributes of an object, you can update the __dict__ of an object (unexpected behaviour may occur if any of your column names are equal to any special python methods).

class Data(object):
   def __init__(self, my_excel):
       (...)
       self.__dict__.update(zip(names, values))

data = Data("test.xls")
print data.a


The traditional approach would be to stuff the key/value pairs into a dict so that you can easily pass the whole structure around to other functions. If you really want to store them as attributes instead of dict keys, consider creating a class to hold them:

class Values(object): pass
store = Values()
for key, value in zip(names, values):
    setattr(store, key, value)

That keeps the variables in their own namespace, separate from your running code. That's almost always a Good Thing. What if you get a spreadsheet with a header called "my_excel"? Suddenly you've lost access to your original my_excel object, which would be very inconvenient if you needed it again.

But in any case, you should never use exec unless you know exactly what you're doing. And even then, don't use exec. For instance, I know how your code works and send you a spreadsheet with "os.system('echo rm -rf *')" in a cell. You probably don't really want to execute that.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜